clean up feed decay

This commit is contained in:
Andre Staltz 2023-09-13 17:10:16 +03:00
parent 56ac4f986e
commit 34cf50b320
No known key found for this signature in database
GPG Key ID: 9EDE23EA7E8A4890
3 changed files with 86 additions and 11 deletions

View File

@ -7,13 +7,28 @@ module.exports = {
permissions: {
anonymous: {},
},
/**
* @param {any} peer
* @param {{
* gc?: {
* maxLogBytes?: number
* }
* }} config
*/
init(peer, config) {
// Assertions
if (!peer.goals) throw new Error('gc requires the goals plugin')
if (typeof config.gc?.maxLogBytes !== 'number') {
throw new Error('gc requires config.gc.maxLogBytes')
}
// State
const debug = makeDebug('ppppp:gc')
function purgeGoallessMsgs(cb) {
debug('purge goalless msgs')
const done = multicb()
function cleanup(cb) {
debug('cleanup goalless started')
const done = multicb({ pluck: 1 })
let waitingForDels = false
for (const rec of peer.db.records()) {
if (!rec.msg) continue
@ -21,17 +36,22 @@ module.exports = {
if (goals.length === 0) {
peer.db.del(rec.id, done())
waitingForDels = true
} else {
}
}
if (waitingForDels) done(cb)
else cb()
function whenEnded(err) {
// prettier-ignore
if (err) debug('cleanup goalless ended with an error %s', err.message ?? err)
else debug('cleanup goalless ended')
cb()
}
if (waitingForDels) done(whenEnded)
else whenEnded()
}
function initiate() {}
function forceImmediately(cb) {
debug('force immediately')
purgeGoallessMsgs(cb)
cleanup(cb)
}
return {

52
test/feed-decay.test.js Normal file
View File

@ -0,0 +1,52 @@
const test = require('node:test')
const assert = require('node:assert')
const p = require('node:util').promisify
const { createPeer } = require('./util')
function getTexts(msgs) {
return msgs.filter((msg) => msg.data?.text).map((msg) => msg.data.text)
}
test('feed decay', async (t) => {
const alice = createPeer({
name: 'alice',
gc: { maxLogBytes: 100 * 1024 * 1024 },
})
await alice.db.loaded()
// Alice creates her own account
const aliceID = await p(alice.db.account.create)({
domain: 'account',
_nonce: 'alice',
})
for (let i = 0; i < 5; i++) {
await p(alice.db.feed.publish)({
account: aliceID,
domain: 'post',
data: { text: 'A' + i },
})
}
assert.deepEqual(
getTexts([...alice.db.msgs()]),
['A0', 'A1', 'A2', 'A3', 'A4'],
'alice has the whole feed'
)
alice.goals.set(aliceID, 'all') // alice wants her account tangle
const postFeedID = alice.db.feed.getID(aliceID, 'post')
alice.goals.set(postFeedID, 'newest-3')
assert('alice set a goal for newest-3 of post feed')
await p(alice.gc.forceImmediately)()
assert.deepEqual(
getTexts([...alice.db.msgs()]),
['A2', 'A3', 'A4'],
'alice has only latest 3 msgs in the feed'
)
await p(alice.close)(true)
})

View File

@ -11,8 +11,11 @@ function getTexts(msgs) {
return msgs.filter((msg) => msg.data?.text).map((msg) => msg.data.text)
}
test('purge an orphan weave', async (t) => {
const alice = createPeer({ name: 'alice' })
test('orphan weave msgs', async (t) => {
const alice = createPeer({
name: 'alice',
gc: { maxLogBytes: 100 * 1024 * 1024 },
})
await alice.db.loaded()
@ -27,7 +30,7 @@ test('purge an orphan weave', async (t) => {
keypair: bobKeypair,
_nonce: 'bob',
})
// Alice creates Bob
// Alice creates Carol
const carolID = await p(alice.db.account.create)({
domain: 'account',
keypair: carolKeypair,