ref-count chainHead_v1_unpin across shared follow#27
Conversation
⚡ Performance Report
|
Bundle Size ReportChunks over 500 KB:
All files
Commit: 20e6294 |
|
❌ E2E Product suite failed on Failed tests: Logs: https://github.com/paritytech/dotli-community/actions/runs/27579711084 |
Two sessions sharing one coalesced chainHead_v1_follow each forward their own chainHead_v1_unpin for the same block, so the broker sends two unpins to the single shared upstream. unfollow is ref-counted across sessions but unpin is not.
Sessions sharing one coalesced chainHead_v1_follow each receive every reported block and unpin independently, but the upstream pinned each block only once. Forwarding every unpin sent duplicates to the single shared follow (double-unpin). Track pin holders per shared follow (block hash -> set of local follow tokens) and forward the upstream unpin only when the last holder releases the block, mirroring the existing unfollow ref-counting. The local unpin response is synthesized so it no longer depends on the upstream reply. On disconnect/unfollow a leaving session's orphaned blocks are unpinned upstream while the follow stays alive; the last token's unfollow releases the rest.
f7ef973 to
060d5a4
Compare
| continue; | ||
| } | ||
| if (holders.size === 0) { | ||
| sharedFollow.pins.delete(hash); |
There was a problem hiding this comment.
Should we include sharedFollow.pins.delete(hash);?
There was a problem hiding this comment.
Not needed for dedup reasons.
This is to prevent a leak. if none of the pins (subscriptions) is holding the block, then the block entry is no longer needed and might be dropped from such from pins list.
…-broker-double-unpin
Fixes #26
Problem
When two tabs share one coalesced
chainHead_v1_follow, the broker forwarded a duplicatechainHead_v1_unpinupstream for the same block — a double-unpin on a single subscription.unfollowwas ref-counted across sessions; unpin` was not.Fix
Ref-count pinned blocks per
SharedFollow(block hash → holding follow tokens), mirroring the existingunfollowhandling:initialized,newBlock) is delivered to a session — for live events and replayed snapshots to late joiners.unpin, drop the session's hold and forward upstream only when no other session still holds the block; reply success locally.Tests
packages/protocol/tests/broker.test.ts: