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

Commit e6ad63e

Browse files
alanshawdaviddias
authored andcommitted
fix: double pre start (#1437)
* fix: double pre start call License: MIT Signed-off-by: Alan Shaw <[email protected]> * fix: initialize event only after repo initializes License: MIT Signed-off-by: Alan Shaw <[email protected]> * fix: call callback License: MIT Signed-off-by: Alan Shaw <[email protected]> * fix: error message regex License: MIT Signed-off-by: Alan Shaw <[email protected]> * fix: typo on intial state name and other fixes License: MIT Signed-off-by: Alan Shaw <[email protected]> * fix: simplify License: MIT Signed-off-by: Alan Shaw <[email protected]> * fix: remove unused preStart and preStarted state changers License: MIT Signed-off-by: Alan Shaw <[email protected]> * fix: error message regex License: MIT Signed-off-by: Alan Shaw <[email protected]>
1 parent b9e6495 commit e6ad63e

File tree

6 files changed

+112
-118
lines changed

6 files changed

+112
-118
lines changed

src/cli/commands/daemon.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ module.exports = {
3535
httpAPI = new HttpAPI(process.env.IPFS_PATH, null, argv)
3636

3737
httpAPI.start((err) => {
38-
if (err && err.code === 'ENOENT' && err.message.match(/Uninitalized repo/i)) {
38+
if (err && err.code === 'ENOENT' && err.message.match(/uninitialized/i)) {
3939
print('Error: no initialized ipfs repo found in ' + repoPath)
4040
print('please run: jsipfs init')
4141
process.exit(1)

src/core/boot.js

Lines changed: 59 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
'use strict'
22

33
const waterfall = require('async/waterfall')
4-
const series = require('async/series')
5-
const extend = require('deep-extend')
64
const RepoErrors = require('ipfs-repo').errors
75

86
// Boot an IPFS node depending on the options set
@@ -11,110 +9,79 @@ module.exports = (self) => {
119
const options = self._options
1210
const doInit = options.init
1311
const doStart = options.start
14-
const config = options.config
15-
const setConfig = config && typeof config === 'object'
16-
const repoOpen = !self._repo.closed
1712

18-
const customInitOptions = typeof options.init === 'object' ? options.init : {}
19-
const initOptions = Object.assign({ bits: 2048, pass: self._options.pass }, customInitOptions)
20-
21-
// Checks if a repo exists, and if so opens it
22-
// Will return callback with a bool indicating the existence
23-
// of the repo
24-
const maybeOpenRepo = (cb) => {
25-
// nothing to do
26-
if (repoOpen) {
27-
return cb(null, true)
28-
}
13+
// Do the actual boot sequence
14+
waterfall([
15+
// Checks if a repo exists, and if so opens it
16+
// Will return callback with a bool indicating the existence
17+
// of the repo
18+
(cb) => {
19+
// nothing to do
20+
if (!self._repo.closed) {
21+
return cb(null, true)
22+
}
2923

30-
series([
31-
(cb) => self._repo.open(cb),
32-
(cb) => self.pin._load(cb),
33-
(cb) => self.preStart(cb),
34-
(cb) => {
35-
self.log('initialized')
36-
self.state.initialized()
24+
self._repo.open((err, res) => {
25+
if (isRepoUninitializedError(err)) return cb(null, false)
26+
if (err) return cb(err)
3727
cb(null, true)
28+
})
29+
},
30+
(repoOpened, cb) => {
31+
// Init with existing initialized, opened, repo
32+
if (repoOpened) {
33+
return self.init({ repo: self._repo }, (err) => cb(err))
3834
}
39-
], (err, res) => {
40-
if (err) {
41-
// If the error is that no repo exists,
42-
// which happens when the version file is not found
43-
// we just want to signal that no repo exist, not
44-
// fail the whole process.
4535

46-
// Use standardized errors as much as possible
47-
if (err.code === RepoErrors.ERR_REPO_NOT_INITIALIZED) {
48-
return cb(null, false)
49-
}
50-
51-
// TODO: As error codes continue to be standardized, this logic can be phase out;
52-
// it is here to maintain compatability
53-
if (err.message.match(/not found/) || // indexeddb
54-
err.message.match(/ENOENT/) || // fs
55-
err.message.match(/No value/) // memory
56-
) {
57-
return cb(null, false)
58-
}
59-
return cb(err)
36+
if (doInit) {
37+
const initOptions = Object.assign(
38+
{ bits: 2048, pass: self._options.pass },
39+
typeof options.init === 'object' ? options.init : {}
40+
)
41+
return self.init(initOptions, (err) => cb(err))
6042
}
61-
cb(null, res)
62-
})
63-
}
6443

65-
const done = (err) => {
44+
cb()
45+
},
46+
(cb) => {
47+
// No problem, we don't have to start the node
48+
if (!doStart) {
49+
return cb()
50+
}
51+
self.start(cb)
52+
}
53+
], (err) => {
6654
if (err) {
6755
return self.emit('error', err)
6856
}
69-
self.log('boot:done')
57+
self.log('booted')
7058
self.emit('ready')
71-
}
72-
73-
const tasks = []
74-
75-
// check if there as a repo and if so open it
76-
maybeOpenRepo((err, hasRepo) => {
77-
if (err) {
78-
return done(err)
79-
}
59+
})
60+
}
8061

81-
// No repo, but need should init one
82-
if (doInit && !hasRepo) {
83-
tasks.push((cb) => self.init(initOptions, cb))
84-
// we know we will have a repo for all follwing tasks
85-
// if the above succeeds
86-
hasRepo = true
87-
}
62+
function isRepoUninitializedError (err) {
63+
if (!err) {
64+
return false
65+
}
8866

89-
// Need to set config
90-
if (setConfig) {
91-
if (!hasRepo) {
92-
console.log('WARNING, trying to set config on uninitialized repo, maybe forgot to set "init: true"')
93-
} else {
94-
tasks.push((cb) => {
95-
waterfall([
96-
(cb) => self.config.get(cb),
97-
(config, cb) => {
98-
extend(config, options.config)
67+
// If the error is that no repo exists,
68+
// which happens when the version file is not found
69+
// we just want to signal that no repo exist, not
70+
// fail the whole process.
9971

100-
self.config.replace(config, cb)
101-
}
102-
], cb)
103-
})
104-
}
105-
}
72+
// Use standardized errors as much as possible
73+
if (err.code === RepoErrors.ERR_REPO_NOT_INITIALIZED) {
74+
return true
75+
}
10676

107-
// Need to start up the node
108-
if (doStart) {
109-
if (!hasRepo) {
110-
console.log('WARNING, trying to start ipfs node on uninitialized repo, maybe forgot to set "init: true"')
111-
return done(new Error('Uninitalized repo'))
112-
} else {
113-
tasks.push((cb) => self.start(cb))
114-
}
115-
}
77+
// TODO: As error codes continue to be standardized, this logic can be phase out;
78+
// it is here to maintain compatability
79+
if (err.message.match(/not found/) || // indexeddb
80+
err.message.match(/ENOENT/) || // fs
81+
err.message.match(/No value/) // memory
82+
) {
83+
return true
84+
}
11685

117-
// Do the actual boot sequence
118-
series(tasks, done)
119-
})
86+
return false
12087
}

src/core/components/init.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,31 @@ module.exports = function init (self) {
2222
return callback(err)
2323
}
2424

25-
self.state.initialized()
26-
self.emit('init')
27-
callback(null, res)
25+
self.preStart((err) => {
26+
if (err) {
27+
self.emit('error', err)
28+
return callback(err)
29+
}
30+
31+
self.state.initialized()
32+
self.emit('init')
33+
callback(null, res)
34+
})
2835
}
2936

30-
if (self.state.state() !== 'uninitalized') {
37+
if (self.state.state() !== 'uninitialized') {
3138
return done(new Error('Not able to init from state: ' + self.state.state()))
3239
}
3340

3441
self.state.init()
3542
self.log('init')
3643

44+
// An initialized, open repo was passed, use this one!
45+
if (opts.repo) {
46+
self._repo = opts.repo
47+
return done(null, true)
48+
}
49+
3750
opts.emptyRepo = opts.emptyRepo || false
3851
opts.bits = Number(opts.bits) || 2048
3952
opts.log = opts.log || function () {}

src/core/components/pre-start.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ const PeerInfo = require('peer-info')
55
const multiaddr = require('multiaddr')
66
const waterfall = require('async/waterfall')
77
const Keychain = require('libp2p-keychain')
8+
const extend = require('deep-extend')
89
const NoKeychain = require('./no-keychain')
910
/*
1011
* Load stuff from Repo into memory
@@ -16,6 +17,21 @@ module.exports = function preStart (self) {
1617
const pass = self._options.pass
1718
waterfall([
1819
(cb) => self._repo.config.get(cb),
20+
(config, cb) => {
21+
if (!self._options.config) {
22+
return cb(null, config)
23+
}
24+
25+
extend(config, self._options.config)
26+
27+
self.config.replace(config, (err) => {
28+
if (err) {
29+
return cb(err)
30+
}
31+
32+
cb(null, config)
33+
})
34+
},
1935
(config, cb) => {
2036
// Create keychain configuration, if needed.
2137
if (config.Keychain) {
@@ -78,7 +94,8 @@ module.exports = function preStart (self) {
7894
}
7995

8096
cb()
81-
}
97+
},
98+
(cb) => self.pin._load(cb)
8299
], callback)
83100
}
84101
}

src/core/components/start.js

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ const promisify = require('promisify-es6')
77

88
module.exports = (self) => {
99
return promisify((callback) => {
10-
callback = callback || function noop () {}
11-
1210
const done = (err) => {
1311
if (err) {
1412
setImmediate(() => self.emit('error', err))
@@ -21,32 +19,31 @@ module.exports = (self) => {
2119
}
2220

2321
if (self.state.state() !== 'stopped') {
24-
return done(new Error('Not able to start from state: ' + self.state.state()))
22+
return done(new Error(`Not able to start from state: ${self.state.state()}`))
2523
}
2624

2725
self.log('starting')
2826
self.state.start()
2927

3028
series([
3129
(cb) => {
30+
// The repo may be closed if previously stopped
3231
self._repo.closed
3332
? self._repo.open(cb)
3433
: cb()
3534
},
36-
(cb) => self.preStart(cb),
37-
(cb) => self.libp2p.start(cb)
38-
], (err) => {
39-
if (err) { return done(err) }
40-
41-
self._bitswap = new Bitswap(
42-
self._libp2pNode,
43-
self._repo.blocks,
44-
{ statsEnabled: true }
45-
)
46-
47-
self._bitswap.start()
48-
self._blockService.setExchange(self._bitswap)
49-
done()
50-
})
35+
(cb) => self.libp2p.start(cb),
36+
(cb) => {
37+
self._bitswap = new Bitswap(
38+
self._libp2pNode,
39+
self._repo.blocks,
40+
{ statsEnabled: true }
41+
)
42+
43+
self._bitswap.start()
44+
self._blockService.setExchange(self._bitswap)
45+
cb()
46+
}
47+
], done)
5148
})
5249
}

src/core/state.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ log.error = debug('jsipfs:state:error')
77
const fsm = require('fsm-event')
88

99
module.exports = (self) => {
10-
const s = fsm('uninitalized', {
11-
uninitalized: {
10+
const s = fsm('uninitialized', {
11+
uninitialized: {
1212
init: 'initializing',
1313
initialized: 'stopped'
1414
},

0 commit comments

Comments
 (0)