| … | … | @@ -47,8 +47,8 @@ async function projectRepo (device, repo) { |
| 47 | 47 | |
| 48 | 48 | // Append any NOT-yet-projected __commit__ frames into the FirehoseSequencer, in seq order. Idempotent |
| 49 | 49 | // (only entries with seq > sequencer.length). Deterministic across devices (same __commit__ order). |
| 50 | | async function projectFirehose (device, seq) { |
| 51 | | const log = await device.firehoseLog() // seq-ordered |
| 50 | async function projectFirehose (device, seq, log = null) { |
| 51 | if (!log) log = await device.firehoseLog() // seq-ordered |
| 52 | 52 | for (let i = seq.length; i < log.length; i++) { |
| 53 | 53 | const write = deserializeEntry(log[i]) |
| 54 | 54 | // time is derived deterministically from the rev so every device emits an identical frame |
| … | … | @@ -75,7 +75,19 @@ export async function serveMembrane (device, { corestore, swarm, did, handle, se |
| 75 | 75 | if (!corestore || !swarm || !did) throw new Error('serveMembrane: corestore, swarm, did required') |
| 76 | 76 | const repo = await new RepoStore(corestore, { name: 'membrane-repo:' + did }).ready() |
| 77 | 77 | const seq = await new FirehoseSequencer(corestore.get({ name: 'membrane-firehose:' + did })).ready() |
| 78 | | const sync = async () => { await projectRepo(device, repo); await projectFirehose(device, seq) } |
| 78 | // Project ONLY when the device's __commit__ log has advanced past what the membrane firehose already |
| 79 | // holds. WITHOUT this gate, the caller's sign loop (every signIntervalMs, ~2s) called sync() |
| 80 | // UNCONDITIONALLY, and projectRepo re-put ALL records into the APPEND-ONLY Hyperbee repo core on EVERY |
| 81 | // tick — even with zero new commits — growing it ~one record-set / 2s → 1.3M blocks / GB in hours, a |
| 82 | // runaway storage+CPU leak (favela then re-replicates the bloated core at ~100 MB/s). projectFirehose |
| 83 | // was already incremental; projectRepo was not. After a full projection seq.length === log.length, so |
| 84 | // `log.length <= seq.length` means there is nothing new to project — skip both (read-only, no writes). |
| 85 | const sync = async () => { |
| 86 | const log = await device.firehoseLog() |
| 87 | if (log.length <= seq.length) return |
| 88 | await projectRepo(device, repo) |
| 89 | await projectFirehose(device, seq, log) |
| 90 | } |
| 79 | 91 | await sync() |
| 80 | 92 | |
| 81 | 93 | const serverKey = b4a.toString(swarm.keyPair.publicKey, 'hex') |