Skip to content

fix(host): preserve chain-head operation ordering - #310

Open
replghost wants to merge 1 commit into
mainfrom
fix/host-operation-event-ordering
Open

fix(host): preserve chain-head operation ordering#310
replghost wants to merge 1 commit into
mainfrom
fix/host-operation-event-ordering

Conversation

@replghost

Copy link
Copy Markdown
Contributor

Problem

TruAPI request responses and follow-subscription events travel on independent frames. A fast chain-head body, call, or storage operation can therefore emit its completion event before the provider publishes the JSON-RPC Started(operationId) response. PAPI drops that unknown operation event and can wait indefinitely.

Changes

  • track chain-head operations per follow subscription and operation id
  • buffer operation events until their Started response has been delivered
  • replay buffered storage items and terminal events in arrival order
  • release state on terminal events, explicit stop, unfollow, subscription interruption, and provider close
  • add regression coverage for early call completion and ordered storage replay
  • add the required patch changeset for @parity/product-sdk-host

No public API or consumer migration is required.

Verification

  • pnpm --filter @parity/product-sdk-host test -- --run — 106 passed
  • pnpm --filter @parity/product-sdk-host typecheck
  • pnpm exec biome check packages/host/src/papi-provider.ts
  • git diff --check

@github-actions

Copy link
Copy Markdown

📦 Bundle size impact

Comparing 2026-08-19T15:38:30.636Z2026-08-19T15:38:34.286Z

Package Entry Bundled before Bundled after Δ Ship gzip Δ Shake ratio
🟢 @parity/product-sdk . 6.42 MB 6.42 MB +972 B (+0.0%) 0 B 0% (was 0%)
🟢 @parity/product-sdk ./chain 6.17 MB 6.18 MB +970 B (+0.0%) 0 B 0% (was 0%)
🟢 @parity/product-sdk ./cloud-storage 6.35 MB 6.35 MB +970 B (+0.0%) 0 B 3% (was 3%)
🟢 @parity/product-sdk ./core 6.42 MB 6.42 MB +972 B (+0.0%) 0 B 0% (was 0%)
🟢 @parity/product-sdk ./host 90.0 KB 91.0 KB +976 B (+1.1%) 0 B 2% (was 2%)
🟢 @parity/product-sdk ./react 6.43 MB 6.43 MB +972 B (+0.0%) 0 B 0% (was 0%)
🟢 @parity/product-sdk-chain-client . 6.17 MB 6.18 MB +970 B (+0.0%) 0 B 0% (was 0%)
🟢 @parity/product-sdk-cloud-storage . 6.35 MB 6.35 MB +970 B (+0.0%) 0 B 3% (was 3%)
🟢 @parity/product-sdk-host . 90.0 KB 91.0 KB +976 B (+1.1%) +361 B 2% (was 2%)
🟢 @parity/product-sdk-statement-store . 101.6 KB 102.6 KB +977 B (+0.9%) 0 B 10% (was 10%)

Thresholds — 🟡 ≥10% or ≥5.0 KB · 🟠 ≥20% or ≥15.0 KB (bundled). Percentage only applies once the baseline is ≥ 10 KB. Informational — this check never blocks merge.

@valentinfernandez1 valentinfernandez1 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Just one small comment, you can address it here or on a follow up


let operation = operations.get(operationId);
if (!operation) {
operation = { announced: false, items: [] };

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

A missing entry here doesn't only mean the Started response hasn't landed. It also means the op already
ended (terminal item at :269, stopOperation at :490, failed start request), and both the spec and PAPI's
cancel path can still emit events after that, so those get buffered and never freed until unfollow.
Suggestion: keep a per-follow counter of start requests still waiting for a response. Only buffer while
that counter is above zero. If it's zero, no Started response can claim this event, so forward it and let
PAPI ignore it like it did before.

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.

2 participants