Skip to content
This repository has been archived by the owner on Dec 28, 2022. It is now read-only.

Add preupgrade hook #129

Closed
wants to merge 15 commits into from
Closed
37 changes: 37 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,10 @@ module.exports = class Hypercore extends EventEmitter {
this._preappend = preappend.bind(this)
this._snapshot = null
this._findingPeers = 0

this._preupgrade = opts.preupgrade || null
this._preupgradeLength = null
this._postupgradeLength = null
}

[inspect] (depth, opts) {
Expand Down Expand Up @@ -447,6 +451,7 @@ module.exports = class Hypercore extends EventEmitter {
}

get length () {
if (this._preupgradeLength !== null) return this._preupgradeLength
if (this._snapshot) return this._snapshot.length
if (this.core === null) return 0
if (!this.sparse) return this.contiguousLength
Expand Down Expand Up @@ -613,8 +618,40 @@ module.exports = class Hypercore extends EventEmitter {
const activeRequests = (opts && opts.activeRequests) || this.activeRequests
const req = this.replicator.addUpgrade(activeRequests)

if (this._preupgrade && this._preupgradeLength === null) {
this._preupgradeLength = this.core.tree.length
}

let upgraded = await req.promise

if (this._preupgrade) {
if (this._postupgradeLength === null) {
const latest = this.session()

this._postupgradeLength = Promise.resolve(this._preupgrade(latest))
this._postupgradeLength
.then(() => latest.close())
.catch(noop)
kasperisager marked this conversation as resolved.
Show resolved Hide resolved
}

const length = await this._postupgradeLength
const preupgradeLength = this._preupgradeLength

this._preupgradeLength = null
this._postupgradeLength = null

if (typeof length === 'number' && length >= preupgradeLength && length < this.core.tree.length) {
this._snapshot = {
length,
byteLength: 0,
fork: this.core.tree.fork,
compatLength: length
}

return length !== preupgradeLength
}
}

if (!this.sparse) {
// Download all available blocks in non-sparse mode
const start = this.length
Expand Down
80 changes: 80 additions & 0 deletions test/preupgrade.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
const test = require('brittle')
const { create, replicate } = require('./helpers')

test('upgrade to latest length', async function (t) {
const a = await create()
await a.append(['a', 'b', 'c'])

const b = await create(a.key, {
preupgrade (latest) {
t.is(b.length, 0)
t.is(latest.length, 3)

return latest.length
}
})

replicate(a, b, t)
t.is(b.length, 0)

t.ok(await b.update())
t.is(b.length, 3)
})

test('stay on previous length', async function (t) {
const a = await create()
await a.append(['a', 'b', 'c'])

const b = await create(a.key, {
preupgrade (latest) {
t.is(b.length, 0)
t.is(latest.length, 3)

return 0
}
})

replicate(a, b, t)
t.is(b.length, 0)

t.absent(await b.update())
t.is(b.length, 0)
})

test('return no length', async function (t) {
const a = await create()
await a.append(['a', 'b', 'c'])

const b = await create(a.key, {
preupgrade (latest) {
t.is(b.length, 0)
t.is(latest.length, 3)
}
})

replicate(a, b, t)
t.is(b.length, 0)

t.ok(await b.update())
t.is(b.length, 3)
})

test('return invalid length', async function (t) {
const a = await create()
await a.append(['a', 'b', 'c'])

const b = await create(a.key, {
preupgrade (latest) {
t.is(b.length, 0)
t.is(latest.length, 3)

return -1
}
})

replicate(a, b, t)
t.is(b.length, 0)

t.ok(await b.update())
t.is(b.length, 3)
})