Skip to content

feat(pyth-lazer): coalesce feeds into one bulk subscription#143

Open
jaspersagent wants to merge 2 commits into
sedaprotocol:mainfrom
jaspersagent:feat/pyth-lazer-bulk-subscribe
Open

feat(pyth-lazer): coalesce feeds into one bulk subscription#143
jaspersagent wants to merge 2 commits into
sedaprotocol:mainfrom
jaspersagent:feat/pyth-lazer-bulk-subscribe

Conversation

@jaspersagent

@jaspersagent jaspersagent commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Per-feed Pyth Lazer subscriptions make the upstream send one WS frame per feed per channel tick, which saturates the single event loop: request latency tails and price staleness both balloon, and the congestion spills onto unrelated routes that share the proxy process.

Per-feed subscriptions made the upstream send one WS frame per feed per
channel tick (~3300 frames/s at production scale), saturating the single
event loop and inflating both request latency tails and price staleness.
New feeds still get an immediate individual subscription for fast first
price, but a periodic compaction pass folds every delivering subscription
into one bulk subscription make-before-break and drops idle feeds, cutting
the standing frame rate to one frame per tick. Feeds that never deliver are
never absorbed, so a single entitlement-failing feed cannot poison the bulk
subscription.
Address audit of the bulk-subscription change. The compaction interval and
make-before-break overlap move from process env to per-module config
(bulkCompactInterval, bulkOverlap) so they validate and tune like the other
module knobs. Compaction now unsubscribes an individual subscription that was
re-created during the overlap window instead of orphaning it, with a test
covering the expire-and-re-request race. The reverse symbol lookup iterates
the map directly instead of copying it, and subscription ids carry a
SubscriptionId type with consistent individual-subscription naming.
return;
}
sendSubscribe(newBulkSubscriptionId, [...newFeedIds]);
yield* Effect.sleep(config.bulkOverlap);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure a sleep is the best approach here.

// Bulk-subscribe bookkeeping: which subscription ids are individual
// subscriptions, which feeds the current bulk subscription carries, and
// which feeds have delivered at least one update. Feeds that never
// deliver (e.g. entitlement failures) are never absorbed into the bulk

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are entitlement failures?

Comment on lines +328 to +331
if (
current.value !== newBulkSubscriptionId &&
individualSubscriptionIds.has(current.value)
) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Woundn't the first condition here always hold since we never assign newBulkSubscriptionId to the feeds during compaction?

const carriedOver = new Set<PriceFeedId>();
let droppedFromBulk = 0;
for (const feedId of bulkFeedIds) {
if (MutableHashMap.has(subscriptions, feedId)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, this check might not enough because a feed that's been cleaned up due to idleness could be re-subscribed. Under this scenario, we would be carrying over the feed without checking deliveredFeedIds.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose we could just assume that a feed that has been included in a bulk has been delivered at least once. Or I think we can just add a subscription ID check?

for (const feedId of bulkFeedIds) {
	const subId = MutableHashMap.get(subscriptions, feedId);
	if (Option.isNone(subId)) {
		// Feed has been cleaned up due to idleness
		droppedFromBulk++;
	} else if (subId.value === bulkSubscriptionId) {
		// Carry over
		carriedOver.add(feedId);
	} else {
		// Feed is back on an individual subscription through re-subscribe
		// Do not carry over and let it be handled as an absorbable case.
		droppedFromBulk++;
	}
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants