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

perf(cli): load only requested sub-system modules and inline require ipfs and ipfs-api #1350

Merged
merged 1 commit into from
May 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions src/cli/bin.js
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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