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
34 changes: 34 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ module.exports = class Hypercore extends EventEmitter {
this._preappend = preappend.bind(this)
this._snapshot = null
this._findingPeers = 0

this._preupgrade = opts.preupgrade || null
this._preupgrading = null
}

[inspect] (depth, opts) {
Expand Down Expand Up @@ -613,8 +616,39 @@ module.exports = class Hypercore extends EventEmitter {
const activeRequests = (opts && opts.activeRequests) || this.activeRequests
const req = this.replicator.addUpgrade(activeRequests)

if (this._preupgrade) this._updateSnapshot()

let upgraded = await req.promise

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

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

const length = await this._preupgrading
const preupgradeLength = this._snapshot.length

this._preupgrading = null
kasperisager marked this conversation as resolved.
Show resolved Hide resolved

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
}

return this._updateSnapshot()
}

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)
})