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

Commit 3820be0

Browse files
alanshawdaviddias
authored andcommitted
perf(cli): load only sub-system modules and inline require ipfs
License: MIT Signed-off-by: Alan Shaw <[email protected]>
1 parent de95989 commit 3820be0

File tree

3 files changed

+58
-43
lines changed

3 files changed

+58
-43
lines changed

src/cli/bin.js

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
const yargs = require('yargs')
66
const updateNotifier = require('update-notifier')
77
const readPkgUp = require('read-pkg-up')
8+
const fs = require('fs')
9+
const path = require('path')
810
const utils = require('./utils')
911
const print = utils.print
1012

@@ -16,6 +18,10 @@ updateNotifier({
1618

1719
const args = process.argv.slice(2)
1820

21+
// Determine if the first argument is a sub-system command
22+
const commandNames = fs.readdirSync(path.join(__dirname, 'commands'))
23+
const isCommand = commandNames.includes(`${args[0]}.js`)
24+
1925
const cli = yargs
2026
.option('silent', {
2127
desc: 'Write no output',
@@ -28,7 +34,14 @@ const cli = yargs
2834
type: 'string',
2935
default: ''
3036
})
31-
.commandDir('commands')
37+
.commandDir('commands', {
38+
// Only include the commands for the sub-system we're using, or include all
39+
// if no sub-system command has been passed.
40+
include (path, filename) {
41+
if (!isCommand) return true
42+
return `${args[0]}.js` === filename
43+
}
44+
})
3245
.epilog(utils.ipfsPathHelp)
3346
.demandCommand(1)
3447
.fail((msg, err, yargs) => {
@@ -43,16 +56,19 @@ const cli = yargs
4356
yargs.showHelp()
4457
})
4558

46-
// NOTE: This creates an alias of
47-
// `jsipfs files {add, get, cat}` to `jsipfs {add, get, cat}`.
48-
// This will stay until https://github.com/ipfs/specs/issues/98 is resolved.
49-
const addCmd = require('./commands/files/add')
50-
const catCmd = require('./commands/files/cat')
51-
const getCmd = require('./commands/files/get')
52-
const aliases = [addCmd, catCmd, getCmd]
53-
aliases.forEach((alias) => {
54-
cli.command(alias.command, alias.describe, alias.builder, alias.handler)
55-
})
59+
// If not a sub-system command then load the top level aliases
60+
if (!isCommand) {
61+
// NOTE: This creates an alias of
62+
// `jsipfs files {add, get, cat}` to `jsipfs {add, get, cat}`.
63+
// This will stay until https://github.com/ipfs/specs/issues/98 is resolved.
64+
const addCmd = require('./commands/files/add')
65+
const catCmd = require('./commands/files/cat')
66+
const getCmd = require('./commands/files/get')
67+
const aliases = [addCmd, catCmd, getCmd]
68+
aliases.forEach((alias) => {
69+
cli.command(alias.command, alias.describe, alias.builder, alias.handler)
70+
})
71+
}
5672

5773
// Need to skip to avoid locking as these commands
5874
// don't require a daemon

src/cli/utils.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
const fs = require('fs')
44
const os = require('os')
5-
const APIctl = require('ipfs-api')
65
const multiaddr = require('multiaddr')
7-
const IPFS = require('../core')
86
const path = require('path')
97
const debug = require('debug')
108
const log = debug('cli')
@@ -35,6 +33,8 @@ function getAPICtl (apiAddr) {
3533
const apiPath = path.join(exports.getRepoPath(), 'api')
3634
apiAddr = multiaddr(fs.readFileSync(apiPath).toString()).toString()
3735
}
36+
// Required inline to reduce startup time
37+
const APIctl = require('ipfs-api')
3838
return APIctl(apiAddr)
3939
}
4040

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

46+
// Required inline to reduce startup time
47+
const IPFS = require('../core')
4648
const node = new IPFS({
4749
repo: exports.getRepoPath(),
4850
init: false,

test/cli/daemon.js

Lines changed: 27 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ const expect = require('chai').expect
55
const clean = require('../utils/clean')
66
const ipfsCmd = require('../utils/ipfs-exec')
77
const isWindows = require('../utils/platforms').isWindows
8-
const pull = require('pull-stream')
9-
const toPull = require('stream-to-pull-stream')
108
const os = require('os')
119
const path = require('path')
1210
const hat = require('hat')
@@ -37,31 +35,20 @@ function testSignal (ipfs, sig) {
3735
}).then(() => {
3836
const proc = ipfs('daemon')
3937
return new Promise((resolve, reject) => {
40-
pull(
41-
toPull(proc.stdout),
42-
pull.collect((err, res) => {
43-
expect(err).to.not.exist()
44-
const data = res.toString()
45-
if (data.includes(`Daemon is ready`)) {
46-
if (proc.kill(sig)) {
47-
resolve()
48-
} else {
49-
reject(new Error(`Unable to ${sig} process`))
50-
}
38+
proc.stdout.on('data', (data) => {
39+
if (data.toString().includes(`Daemon is ready`)) {
40+
if (proc.kill(sig)) {
41+
resolve()
42+
} else {
43+
reject(new Error(`Unable to ${sig} process`))
5144
}
52-
})
53-
)
54-
55-
pull(
56-
toPull(proc.stderr),
57-
pull.collect((err, res) => {
58-
expect(err).to.not.exist()
59-
const data = res.toString()
60-
if (data.length > 0) {
61-
reject(new Error(data))
62-
}
63-
})
64-
)
45+
}
46+
})
47+
proc.stderr.on('data', (data) => {
48+
if (data.toString().length > 0) {
49+
reject(new Error(data))
50+
}
51+
})
6552
})
6653
})
6754
}
@@ -79,6 +66,8 @@ describe('daemon', () => {
7966

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

8372
ipfs('init').then(() => {
8473
return ipfs('config', 'Addresses', JSON.stringify({
@@ -87,10 +76,18 @@ describe('daemon', () => {
8776
Gateway: '/ip4/127.0.0.1/tcp/0'
8877
}), '--json')
8978
}).then(() => {
90-
return ipfs('daemon')
91-
}).then((res) => {
92-
expect(res).to.have.string('Daemon is ready')
93-
done()
79+
const res = ipfs('daemon')
80+
const timeout = setTimeout(() => {
81+
done(new Error('Daemon did not get ready in time'))
82+
}, 1000 * 120)
83+
res.stdout.on('data', (data) => {
84+
const line = data.toString()
85+
if (line.includes('Daemon is ready')) {
86+
clearTimeout(timeout)
87+
res.kill()
88+
done()
89+
}
90+
})
9491
}).catch(err => done(err))
9592
})
9693

0 commit comments

Comments
 (0)