Skip to content

fix(deno): wake idle serve loops on demand - #398

Merged
momics merged 3 commits into
mainfrom
momics-fix-deno-idle-polling
Aug 28, 2026
Merged

momics merged 3 commits into
mainfrom
momics-fix-deno-idle-polling

Conversation

@momics

@momics momics commented Aug 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • retain the bounded native serve queue and synchronous iroh_http_try_next_request drain required by bug(deno): unknown handle / sendChunk failed under concurrent load — only the Deno adapter is affected #122
  • replace the MessageChannel idle loop with a module-lifetime Deno.UnsafeCallback.threadSafe() notification carrying only an opaque serve-generation token
  • unref the callback so idle servers allow process exit, while preserving shutdown, restart routing, handler draining, connection events, and fail-closed queue behavior
  • correct the Deno FFI architecture documentation and stale callback constraints

Regression evidence

The regression commit deterministically observes synchronous queue drains. On main, an idle server increased from 8,773 to 36,766 polls over a 50 ms idle interval. With the fix, the count remains unchanged until Rust sends a request-ready notification.

Release-build macOS/Deno 2.9.3 measurement:

Path User CPU Wall time
main, idle node without serve() 0.18s 5.86s
main, idle node with serve() 5.47s 5.12s
this branch, idle node with serve() 0.16s 5.70s

Test coverage

  • npm run ci
  • Deno adapter regression suite (13 tests)
  • 32-stream burst × 5 restart iterations
  • 32-stream stop/restart routing regression
  • cargo test -p iroh-http-deno
  • release-build idle CPU measurement

Closes #397

momics and others added 3 commits August 28, 2026 11:39
Reproduces the released busy-poll by observing the synchronous request queue drain path while an idle server has no work. The test fails on main and will pass once request readiness is event-driven.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Keep requests in the bounded native queue and preserve synchronous draining for #122, but replace MessageChannel idle polling with a module-lifetime thread-safe Deno callback carrying an opaque serve-generation token. Unref the callback so idle servers do not hold the process open, and wake shutdown paths without passing borrowed payload pointers across FFI.

Update the Deno bridge architecture documentation and lifecycle comments to match the event-driven design.

Closes #397

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Restore the surrounding document formatting changed by the formatter while retaining only the architecture updates required for the event-driven Deno serve bridge.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@momics
momics merged commit 1182f95 into main Aug 28, 2026
8 checks passed
@momics
momics deleted the momics-fix-deno-idle-polling branch August 28, 2026 11:24
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.

Idle busy-poll of iroh_http_try_next_request saturates one CPU core per HTTPi-enabled node

1 participant