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

Commit 1e6bc09

Browse files
committed
feat: preload mfs root preiodically and preload dag.put
License: MIT Signed-off-by: Alan Shaw <[email protected]>
1 parent 67300cc commit 1e6bc09

File tree

9 files changed

+87
-7
lines changed

9 files changed

+87
-7
lines changed

src/core/components/dag.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@ module.exports = function dag (self) {
2424

2525
options = options.cid ? options : Object.assign({}, optionDefaults, options)
2626

27-
self._ipld.put(dagNode, options, callback)
27+
self._ipld.put(dagNode, options, (err, cid) => {
28+
if (err) return callback(err)
29+
if (options.preload !== false) self._preload(cid)
30+
callback(null, cid)
31+
})
2832
}),
2933

3034
get: promisify((cid, path, options, callback) => {

src/core/components/index.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,4 @@ exports.dht = require('./dht')
2626
exports.dns = require('./dns')
2727
exports.key = require('./key')
2828
exports.stats = require('./stats')
29-
exports.mfs = require('ipfs-mfs/core')
29+
exports.mfs = require('./mfs')

src/core/components/mfs.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict'
2+
3+
const promisify = require('promisify-es6')
4+
const mfs = require('ipfs-mfs/core')
5+
6+
module.exports = self => {
7+
const mfsSelf = Object.assign({}, self)
8+
9+
// A patched dag API to ensure preload doesn't happen for MFS operations
10+
mfsSelf.dag = Object.assign({}, self.dag, {
11+
put: promisify((node, opts, cb) => {
12+
if (typeof opts === 'function') {
13+
cb = opts
14+
opts = {}
15+
}
16+
17+
opts = Object.assign({}, opts, { preload: false })
18+
19+
return self.dag.put(node, opts, cb)
20+
})
21+
})
22+
23+
return mfs(mfsSelf, mfsSelf._options)
24+
}

src/core/components/pin-set.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ exports = module.exports = function (dag) {
9090

9191
pinSet.storeItems(pins, (err, rootNode) => {
9292
if (err) { return callback(err) }
93-
const opts = { cid: new CID(rootNode.multihash) }
93+
const opts = { cid: new CID(rootNode.multihash), preload: false }
9494
dag.put(rootNode, opts, (err, cid) => {
9595
if (err) { return callback(err) }
9696
callback(null, rootNode)
@@ -168,7 +168,8 @@ exports = module.exports = function (dag) {
168168
function storeChild (err, child, binIdx, cb) {
169169
if (err) { return cb(err) }
170170

171-
dag.put(child, { cid: new CID(child._multihash) }, err => {
171+
const opts = { cid: new CID(child._multihash), preload: false }
172+
dag.put(child, opts, err => {
172173
if (err) { return cb(err) }
173174
fanoutLinks[binIdx] = new DAGLink('', child.size, child.multihash)
174175
cb(null)

src/core/components/pin.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,14 +80,14 @@ module.exports = (self) => {
8080
// the pin-set nodes link to a special 'empty' node, so make sure it exists
8181
cb => DAGNode.create(Buffer.alloc(0), (err, empty) => {
8282
if (err) { return cb(err) }
83-
dag.put(empty, { cid: new CID(empty.multihash) }, cb)
83+
dag.put(empty, { cid: new CID(empty.multihash), preload: false }, cb)
8484
}),
8585

8686
// create a root node with DAGLinks to the direct and recursive DAGs
8787
cb => DAGNode.create(Buffer.alloc(0), [dLink, rLink], (err, node) => {
8888
if (err) { return cb(err) }
8989
root = node
90-
dag.put(root, { cid: new CID(root.multihash) }, cb)
90+
dag.put(root, { cid: new CID(root.multihash), preload: false }, cb)
9191
}),
9292

9393
// hack for CLI tests

src/core/components/start.js

+1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ module.exports = (self) => {
3535
(cb) => self.libp2p.start(cb),
3636
(cb) => {
3737
self._preload.start()
38+
self._mfsPreload.start()
3839

3940
self._bitswap = new Bitswap(
4041
self._libp2pNode,

src/core/components/stop.js

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ module.exports = (self) => {
3131
self._blockService.unsetExchange()
3232
self._bitswap.stop()
3333
self._preload.stop()
34+
self._mfsPreload.stop()
3435

3536
series([
3637
(cb) => self.libp2p.stop(cb),

src/core/index.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const components = require('./components')
2323
// replaced by repo-browser when running in the browser
2424
const defaultRepo = require('./runtime/repo-nodejs')
2525
const preload = require('./preload')
26+
const mfsPreload = require('./mfs-preload')
2627

2728
class IPFS extends EventEmitter {
2829
constructor (options) {
@@ -87,6 +88,7 @@ class IPFS extends EventEmitter {
8788
this._ipld = new Ipld(this._blockService)
8889
this._pubsub = undefined
8990
this._preload = preload(this)
91+
this._mfsPreload = mfsPreload(this)
9092

9193
// IPFS Core exposed components
9294
// - for booting up a node
@@ -143,7 +145,7 @@ class IPFS extends EventEmitter {
143145
}
144146

145147
// ipfs.files
146-
const mfs = components.mfs(this, this._options)
148+
const mfs = components.mfs(this)
147149

148150
Object.keys(mfs).forEach(key => {
149151
this.files[key] = mfs[key]

src/core/mfs-preload.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
'use strict'
2+
3+
const debug = require('debug')
4+
5+
const log = debug('jsipfs:mfs-preload')
6+
log.error = debug('jsipfs:mfs-preload:error')
7+
8+
module.exports = (self, options) => {
9+
options = options || {}
10+
options.interval = options.interval || 30 * 1000
11+
12+
let rootCid
13+
let timeoutId
14+
15+
const preloadMfs = () => {
16+
self.files.stat('/', (err, stats) => {
17+
if (err) {
18+
timeoutId = setTimeout(preloadMfs, options.interval)
19+
return log.error('failed to stat MFS root for preload', err)
20+
}
21+
22+
if (rootCid !== stats.hash) {
23+
log(`preloading updated MFS root ${rootCid} -> ${stats.hash}`)
24+
25+
self._preload(stats.hash, (err) => {
26+
timeoutId = setTimeout(preloadMfs, options.interval)
27+
if (err) return log.error(`failed to preload MFS root ${stats.hash}`, err)
28+
rootCid = stats.hash
29+
})
30+
}
31+
})
32+
}
33+
34+
return {
35+
start () {
36+
self.files.stat('/', (err, stats) => {
37+
if (err) return log.error('failed to stat MFS root for preload', err)
38+
rootCid = stats.hash
39+
log(`monitoring MFS root ${rootCid}`)
40+
timeoutId = setTimeout(preloadMfs, options.interval)
41+
})
42+
},
43+
stop () {
44+
clearTimeout(timeoutId)
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)