Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

Commit

Permalink
perf(cli): load only sub-system modules and inline require ipfs
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Alan Shaw <alan@tableflip.io>
  • Loading branch information
alanshaw authored and daviddias committed May 12, 2018
1 parent de95989 commit 3820be0
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 43 deletions.
38 changes: 27 additions & 11 deletions src/cli/bin.js
Expand Up @@ -5,6 +5,8 @@
const yargs = require('yargs')
const updateNotifier = require('update-notifier')
const readPkgUp = require('read-pkg-up')
const fs = require('fs')
const path = require('path')
const utils = require('./utils')
const print = utils.print

Expand All @@ -16,6 +18,10 @@ updateNotifier({

const args = process.argv.slice(2)

// Determine if the first argument is a sub-system command
const commandNames = fs.readdirSync(path.join(__dirname, 'commands'))
const isCommand = commandNames.includes(`${args[0]}.js`)

const cli = yargs
.option('silent', {
desc: 'Write no output',
Expand All @@ -28,7 +34,14 @@ const cli = yargs
type: 'string',
default: ''
})
.commandDir('commands')
.commandDir('commands', {
// Only include the commands for the sub-system we're using, or include all
// if no sub-system command has been passed.
include (path, filename) {
if (!isCommand) return true
return `${args[0]}.js` === filename
}
})
.epilog(utils.ipfsPathHelp)
.demandCommand(1)
.fail((msg, err, yargs) => {
Expand All @@ -43,16 +56,19 @@ const cli = yargs
yargs.showHelp()
})

// NOTE: This creates an alias of
// `jsipfs files {add, get, cat}` to `jsipfs {add, get, cat}`.
// This will stay until https://github.com/ipfs/specs/issues/98 is resolved.
const addCmd = require('./commands/files/add')
const catCmd = require('./commands/files/cat')
const getCmd = require('./commands/files/get')
const aliases = [addCmd, catCmd, getCmd]
aliases.forEach((alias) => {
cli.command(alias.command, alias.describe, alias.builder, alias.handler)
})
// If not a sub-system command then load the top level aliases
if (!isCommand) {
// NOTE: This creates an alias of
// `jsipfs files {add, get, cat}` to `jsipfs {add, get, cat}`.
// This will stay until https://github.com/ipfs/specs/issues/98 is resolved.
const addCmd = require('./commands/files/add')
const catCmd = require('./commands/files/cat')
const getCmd = require('./commands/files/get')
const aliases = [addCmd, catCmd, getCmd]
aliases.forEach((alias) => {
cli.command(alias.command, alias.describe, alias.builder, alias.handler)
})
}

// Need to skip to avoid locking as these commands
// don't require a daemon
Expand Down
6 changes: 4 additions & 2 deletions src/cli/utils.js
Expand Up @@ -2,9 +2,7 @@

const fs = require('fs')
const os = require('os')
const APIctl = require('ipfs-api')
const multiaddr = require('multiaddr')
const IPFS = require('../core')
const path = require('path')
const debug = require('debug')
const log = debug('cli')
Expand Down Expand Up @@ -35,6 +33,8 @@ function getAPICtl (apiAddr) {
const apiPath = path.join(exports.getRepoPath(), 'api')
apiAddr = multiaddr(fs.readFileSync(apiPath).toString()).toString()
}
// Required inline to reduce startup time
const APIctl = require('ipfs-api')
return APIctl(apiAddr)
}

Expand All @@ -43,6 +43,8 @@ exports.getIPFS = (argv, callback) => {
return callback(null, getAPICtl(argv.api), (cb) => cb())
}

// Required inline to reduce startup time
const IPFS = require('../core')
const node = new IPFS({
repo: exports.getRepoPath(),
init: false,
Expand Down
57 changes: 27 additions & 30 deletions test/cli/daemon.js
Expand Up @@ -5,8 +5,6 @@ const expect = require('chai').expect
const clean = require('../utils/clean')
const ipfsCmd = require('../utils/ipfs-exec')
const isWindows = require('../utils/platforms').isWindows
const pull = require('pull-stream')
const toPull = require('stream-to-pull-stream')
const os = require('os')
const path = require('path')
const hat = require('hat')
Expand Down Expand Up @@ -37,31 +35,20 @@ function testSignal (ipfs, sig) {
}).then(() => {
const proc = ipfs('daemon')
return new Promise((resolve, reject) => {
pull(
toPull(proc.stdout),
pull.collect((err, res) => {
expect(err).to.not.exist()
const data = res.toString()
if (data.includes(`Daemon is ready`)) {
if (proc.kill(sig)) {
resolve()
} else {
reject(new Error(`Unable to ${sig} process`))
}
proc.stdout.on('data', (data) => {
if (data.toString().includes(`Daemon is ready`)) {
if (proc.kill(sig)) {
resolve()
} else {
reject(new Error(`Unable to ${sig} process`))
}
})
)

pull(
toPull(proc.stderr),
pull.collect((err, res) => {
expect(err).to.not.exist()
const data = res.toString()
if (data.length > 0) {
reject(new Error(data))
}
})
)
}
})
proc.stderr.on('data', (data) => {
if (data.toString().length > 0) {
reject(new Error(data))
}
})
})
})
}
Expand All @@ -79,6 +66,8 @@ describe('daemon', () => {

skipOnWindows('do not crash if Addresses.Swarm is empty', function (done) {
this.timeout(100 * 1000)
// These tests are flaky, but retrying 3 times seems to make it work 99% of the time
this.retries(3)

ipfs('init').then(() => {
return ipfs('config', 'Addresses', JSON.stringify({
Expand All @@ -87,10 +76,18 @@ describe('daemon', () => {
Gateway: '/ip4/127.0.0.1/tcp/0'
}), '--json')
}).then(() => {
return ipfs('daemon')
}).then((res) => {
expect(res).to.have.string('Daemon is ready')
done()
const res = ipfs('daemon')
const timeout = setTimeout(() => {
done(new Error('Daemon did not get ready in time'))
}, 1000 * 120)
res.stdout.on('data', (data) => {
const line = data.toString()
if (line.includes('Daemon is ready')) {
clearTimeout(timeout)
res.kill()
done()
}
})
}).catch(err => done(err))
})

Expand Down

0 comments on commit 3820be0

Please sign in to comment.