set ghostSpan
This commit is contained in:
parent
06c41a18a9
commit
bb7383aa6d
33
lib/index.js
33
lib/index.js
|
@ -5,14 +5,16 @@ const makeDebug = require('debug')
|
|||
* @typedef {ReturnType<import('ppppp-goals').init>} PPPPPGoal
|
||||
* @typedef {import('ppppp-goals').GoalDSL} GoalDSL
|
||||
* @typedef {ReturnType<import('ppppp-set').init>} PPPPPSet
|
||||
* @typedef {ReturnType<import('ppppp-dict').init>} PPPPPDict
|
||||
* @typedef {ReturnType<import('ppppp-sync').init>} PPPPPSync
|
||||
* @typedef {ReturnType<import('ppppp-gc').init>} PPPPPGC
|
||||
* @typedef {`${string}@${GoalDSL}`} Rule
|
||||
* @typedef {[Array<Rule>, Array<Rule>]} Rules
|
||||
* @typedef {{
|
||||
* db:PPPPPDB | null,
|
||||
* db: PPPPPDB | null,
|
||||
* goals: PPPPPGoal | null,
|
||||
* set: PPPPPSet | null,
|
||||
* dict: PPPPPDict | null,
|
||||
* sync: PPPPPSync | null,
|
||||
* gc: PPPPPGC | null,
|
||||
* }} UnknownPeer
|
||||
|
@ -83,8 +85,24 @@ function initConductor(peer, config) {
|
|||
assertGCPlugin(peer)
|
||||
assertSyncPlugin(peer)
|
||||
|
||||
const ESTIMATE_TOTAL_GHOST_BYTES = 1024 * 1024 // 1 MB
|
||||
const ESTIMATE_MSG_ID_BYTES = 22 // 22 bytes per msg ID
|
||||
|
||||
const debug = makeDebug('ppppp:conductor')
|
||||
|
||||
/**
|
||||
* @param {Array<Rule>} rules
|
||||
*/
|
||||
function countGhostableFeeds(rules) {
|
||||
let count = 2 // 'follow' and 'block' Sets
|
||||
for (const rule of rules) {
|
||||
const [, goalDSL] = parseRule(rule)
|
||||
if (goalDSL === 'dict') count++
|
||||
else if (goalDSL === 'set') count++
|
||||
}
|
||||
return count
|
||||
}
|
||||
|
||||
/**
|
||||
* Set replication goals for various tangles of an account:
|
||||
* - Account tangle
|
||||
|
@ -167,10 +185,9 @@ function initConductor(peer, config) {
|
|||
const [myRules, theirRules] = rules
|
||||
|
||||
// TODO: If goals are too big for maxBytes budget, scale down goals
|
||||
// TODO: Figure out ghost spans for dicts and sets
|
||||
|
||||
// Set up goals for my account and each account I follow
|
||||
setupAccountGoals(myID, myRules)
|
||||
|
||||
const followedAccounts = peer.set.values('follow')
|
||||
for (const theirID of followedAccounts) {
|
||||
setupAccountGoals(theirID, theirRules)
|
||||
|
@ -189,6 +206,16 @@ function initConductor(peer, config) {
|
|||
}
|
||||
})
|
||||
|
||||
// Figure out ghost span for each account
|
||||
const totalGhostableFeeds =
|
||||
countGhostableFeeds(myRules) +
|
||||
followedAccounts.length * countGhostableFeeds(theirRules)
|
||||
const TOTAL_GHOSTS = ESTIMATE_TOTAL_GHOST_BYTES / ESTIMATE_MSG_ID_BYTES
|
||||
const ghostSpan = Math.round(TOTAL_GHOSTS / totalGhostableFeeds)
|
||||
peer.set.setGhostSpan(ghostSpan)
|
||||
peer.dict?.setGhostSpan(ghostSpan)
|
||||
|
||||
// Kick off garbage collection and synchronization
|
||||
peer.gc.start(maxBytes)
|
||||
peer.sync.start()
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
"ppppp-caps": "github:staltz/ppppp-caps",
|
||||
"ppppp-db": "github:staltz/ppppp-db",
|
||||
"ppppp-set": "github:staltz/ppppp-set",
|
||||
"ppppp-dict": "github:staltz/ppppp-dict",
|
||||
"ppppp-gc": "github:staltz/ppppp-gc",
|
||||
"ppppp-goals": "github:staltz/ppppp-goals",
|
||||
"ppppp-keypair": "github:staltz/ppppp-keypair",
|
||||
|
|
|
@ -350,3 +350,48 @@ test('GC recently-blocked accounts', async (t) => {
|
|||
await p(bob.close)(true)
|
||||
await p(carol.close)(true)
|
||||
})
|
||||
|
||||
test('Set and Dict ghost spans', async (t) => {
|
||||
// Alice
|
||||
const alice = createPeer({ name: 'alice' })
|
||||
await alice.db.loaded()
|
||||
// Alice creates her own account
|
||||
const aliceID = await p(alice.db.account.create)({
|
||||
subdomain: 'account',
|
||||
_nonce: 'alice',
|
||||
})
|
||||
await p(alice.set.load)(aliceID)
|
||||
|
||||
// Bob
|
||||
const bob = createPeer({ name: 'bob' })
|
||||
await bob.db.loaded()
|
||||
// Bob creates his own account
|
||||
const bobID = await p(bob.db.account.create)({
|
||||
subdomain: 'account',
|
||||
_nonce: 'bob',
|
||||
})
|
||||
await p(bob.set.load)(bobID)
|
||||
|
||||
// Carol
|
||||
const carol = createPeer({ name: 'carol' })
|
||||
await carol.db.loaded()
|
||||
// Carol creates her own account
|
||||
const carolID = await p(carol.db.account.create)({
|
||||
subdomain: 'account',
|
||||
_nonce: 'carol',
|
||||
})
|
||||
await p(carol.set.load)(bobID)
|
||||
|
||||
// Alice follows Bob, but not Carol
|
||||
assert(await p(alice.set.add)('follow', bobID), 'alice follows bob')
|
||||
|
||||
alice.conductor.start(aliceID, [['post@all'], ['post@all']], 4_000)
|
||||
bob.conductor.start(bobID, [['post@all'], ['post@all']], 4_000)
|
||||
|
||||
assert.equal(alice.set.getGhostSpan(), 11916, 'alice set ghost span is 2')
|
||||
assert.equal(alice.dict.getGhostSpan(), 11916, 'alice set ghost span is 2')
|
||||
|
||||
await p(alice.close)(true)
|
||||
await p(bob.close)(true)
|
||||
await p(carol.close)(true)
|
||||
})
|
||||
|
|
|
@ -22,6 +22,7 @@ function createPeer(opts) {
|
|||
.use(require('ppppp-db'))
|
||||
.use(require('ssb-box'))
|
||||
.use(require('ppppp-set'))
|
||||
.use(require('ppppp-dict'))
|
||||
.use(require('ppppp-goals'))
|
||||
.use(require('ppppp-sync'))
|
||||
.use(require('ppppp-gc'))
|
||||
|
|
Loading…
Reference in New Issue