Skip to content

fix: recover runtime task function operations - #202

Merged
jerome-benoit merged 1 commit into
masterfrom
fix/task-function-recovery
Oct 20, 2026
Merged

jerome-benoit merged 1 commit into
masterfrom
fix/task-function-recovery

Conversation

@jerome-benoit

@jerome-benoit jerome-benoit commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

PR Checklist

  • Conventional Commits title and changes described.
  • Regression tests and existing API documentation updated.
  • Related issues linked.

Does this PR introduce a breaking change?

  • Yes
  • No

Changes

Ports poolifier/poolifier#3369 at 23357872ffd4737198edf2657bbb96778af22654:

  • Recover captured affinity when live metadata is missing, preserving live worker-local default selection.
  • Drain contacted mutation targets after a send failure before releasing FIFO; preserve the original error, including undefined.
  • Retry failed initialization after successful mutations; restore registrations, default and scheduling before readiness. Repeated restoration failure leaves the worker unavailable and emits error without rejecting the successful mutation.

Closes #198, closes #199, closes #200. Targets the current contracts described in the amended port issues.

Fidelity and Web boundaries

AST comparisons confirm the same 12 changed class members as upstream and seven structurally identical copied members. Single-worker replay and cohort ACK handling remain unchanged.

Retain UUIDs, numeric protected hooks, EventTarget errors and two-phase captured-owner exit tracking. The captured-owner iterator needs a membership check when retiring unsent peers. Defer settlement until synchronous dispatch unwinds so a Web exit cannot mask a subsequent send error. Two additional regressions cover these necessary adaptations. No new exports/options or README changes.

Verification

  • All 18 upstream scenarios adapted to Web Workers, plus two synchronous-exit cases; 16 upstream scenarios failed before the fix.
  • Full coverage without retries: 28 suites, 509 passing steps, zero failures; nine existing ignored steps.
  • Real runtime smoke: five scenarios each on Deno 2.9.7, Bun 1.4.2 and Chromium 155; three shared scenarios each on pinned upstream Node threads/cluster.
  • Lint, format, strict source check, browser/Bun builds, DOM/WebWorker declaration consumers and JSR publication dry-run pass.
  • Two independent read-only source/contract reviews: no findings.
  • GitHub checks at a8768f49edbbb6c3c3c2418b755bd3ad86633181: 15/15 passed.

Known shared limitation

Removing the exact registration whose replay failed still rejects when the worker never installed it. Reproduced in the port and pinned upstream; corrective ADD succeeds. Validated review finding remains open. No separate recovery algorithm is introduced here.

Port poolifier/poolifier#3369 at 23357872, retaining synchronous Web lifecycle safeguards.
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-20T18:15:15.466258Z a8768f4 PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a8768f49ed

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +859 to +860
const result = await operation()
await this.retryFailedWorkerTaskFunctionBootstraps()

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Allow removing the registration that caused replay failure

When bootstrap fails because a captured function cannot be installed (for example, its serialized source evaluates to null), calling removeTaskFunction() for that exact function cannot recover the pool: the worker never installed it, so it rejects the remove request, and await operation() throws before the pool deletes the captured registration or retries restoration. The worker therefore remains unavailable and every subsequent removal repeats the same failure; removal should be able to discard a pool-side registration that is absent specifically because this worker's bootstrap failed.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Confirmed, and shared with the pinned upstream implementation rather than introduced by the port. Fresh real-worker reproduction on Deno 2.9.7, Bun 1.4.2 and upstream #3369 23357872ffd4737198edf2657bbb96778af22654 using Node v26.12.0 threads:

  1. Preregister bad with a callable whose toString() returns the string null, then start a fixed one-worker pool. Real worker validation rejects replay.
  2. Two successive public removals both reject with the genuine negative ACK (Unknown error); captured registration remains and readiness stays false.
  3. Corrective public ADD succeeds on the same worker; execution returns 43 and readiness becomes true.

No ACK/readiness is fabricated. The shared queue retries restoration only after await operation() succeeds; the failed remove never deletes captured state. The existing #199 success-after-correction scenario is fixed, but deleting the very absent registration needs an additional upstream recovery policy. Leaving this thread open and recording the limitation in the PR description; no independent algorithm change is silently added to this faithful port.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Upstream report filed: poolifier/poolifier#3370. The port remains unchanged and faithful to upstream #3369; this recovery-policy change is not folded into PR #202.

@sonarqubecloud

Copy link
Copy Markdown

@jerome-benoit
jerome-benoit merged commit ecbadb8 into master Oct 20, 2026
15 checks passed
@jerome-benoit
jerome-benoit deleted the fix/task-function-recovery branch October 20, 2026 18:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant