Skip to content

Commit

Permalink
feat: force kill daemons after timeout (#441)
Browse files Browse the repository at this point in the history
This PR re-adds a feature that was removed in 1.0.0 whereby daemons are force killed with a SIGKILL when they do not stop within a timeout.

It adds 2 new options to the `Daemon` class - `forceKill` (boolean - default `true`) and `forceKillTimeout` (number - default 5000).

closes #438

Co-authored-by: Alex Potsides <alex@achingbrain.net>
  • Loading branch information
Alan Shaw and achingbrain authored Jan 29, 2020
1 parent 9cbf329 commit 182e532
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 2 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@ Type: [Object]
- `ipfsModule.path` **[string]** Path to a IPFS API implementation to be required. (defaults to the local require.resolve('ipfs'))
- `ipfsBin` **[string]** Path to a IPFS exectutable . (defaults to the local 'js-ipfs/src/bin/cli.js')
- `ipfsOptions` **[IpfsOptions]** Options for the IPFS instance same as https://github.com/ipfs/js-ipfs#ipfs-constructor. `proc` nodes receive these options as is, daemon nodes translate the options as far as possible to cli arguments.
- `forceKill` **[boolean]** - Whether to use SIGKILL to quit a daemon that does not stop after `.stop()` is called. (default `true`)
- `forceKillTimeout` **[Number]** - How long to wait before force killing a daemon in ms. (default `5000`)


## ipfsd-ctl environment variables
Expand Down
4 changes: 3 additions & 1 deletion src/factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ const defaults = {
path: require.resolve('ipfs-http-client'),
ref: require('ipfs-http-client')
},
ipfsOptions: {}
ipfsOptions: {},
forceKill: true,
forceKillTimeout: 5000
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ module.exports = {
* @property {string} [ipfsModule.path] - Path to a IPFS API implementation to be required. (defaults to the local require.resolve('ipfs'))
* @property {String} [ipfsBin] - Path to a IPFS exectutable . (defaults to the local 'js-ipfs/src/bin/cli.js')
* @property {IpfsOptions} [ipfsOptions] - Options for the IPFS node.
* @property {boolean} [forceKill] - Whether to use SIGKILL to quit a daemon that does not stop after `.stop()` is called. (default true)
* @property {Number} [forceKillTimeout] - How long to wait before force killing a daemon in ms. (default 5000)
*/

/**
Expand Down
22 changes: 21 additions & 1 deletion src/ipfsd-daemon.js
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,27 @@ class Daemon {
return this
}

await this.api.stop()
let killTimeout
let killed = false
if (this.opts.forceKill !== false) {
killTimeout = setTimeout(() => {
// eslint-disable-next-line no-console
console.error(new Error(`Timeout stopping ${this.opts.type} node. Process ${this.subprocess.pid} will be force killed now.`))
killed = true

this.subprocess.kill('SIGKILL')
}, this.opts.forceKillTimeout)
}

try {
await this.api.stop()
} catch (err) {
if (!killed) throw err // if was killed then ignore error

daemonLog.info('Daemon was force killed')
}

clearTimeout(killTimeout)
this.subprocess.stderr.removeAllListeners()
this.subprocess.stdout.removeAllListeners()
this.started = false
Expand Down

0 comments on commit 182e532

Please sign in to comment.