Skip to content

Add opt-in ordered HTML processor EOF completion - #1290

Open
prk-Jr wants to merge 25 commits into
mainfrom
feat/1241-async-html-finalization
Open

prk-Jr wants to merge 25 commits into
mainfrom
feat/1241-async-html-finalization

Conversation

@prk-Jr

@prk-Jr prk-Jr commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Add opt-in, ordered asynchronous HTML processor completion at document EOF through StreamProcessor::async_finish. Chunk processing remains synchronous. Each stage completes before downstream EOF, and accepted output passes through downstream processing.

Factories declare stable async/retention capabilities and require publisher.allow_async_html_finish = true (default false). Core owns bounded fallback and replacement buffers, one shared deadline, marker validation, and auction/codec ordering. Default EOF settings are omitted from serialized config for compatibility with older binaries. All async input representations share cumulative raw and decoded byte limits.

Non-retaining streaming processors can release ready HTML before optional work. Retention delays initial delivery; Axum, Workers and Spin currently buffer publisher responses. Limits apply per holder, not total request memory. Axum/Workers/Spin timers interrupt yielding work. Fastly checks the budget before and after callbacks and cannot preempt blocking host calls; integrations must bound those calls themselves.

Async capability bypasses processed-template caching before lookup; processed output uses Cache-Control: no-store, private, including fallback. Raw-origin readthrough stays independent. Range-associated HTML preserves encoded bytes and origin metadata without EOF work. Shared-template caching for async output is tracked in #1397.

The feature-gated native runtime harness checks disabled/success/failure/timeout behavior and Fastly early-byte delivery. Its auction control intentionally uses an unreachable bidder and verifies empty-bid script assembly after finalized output; it does not establish successful or delayed bid collection. CI uses the repository-pinned Viceroy shared with ordinary tests and the shared Rust setup action. WASM Clippy also covers Workers/Spin fixture loggers.

Review remediation

  • Fix default config serialization and materialized-body cap bypasses with regressions.
  • Cover direct composite EOF rejection, invalid retention metadata, pre-callback flush, bounded seam prefixes, direct buffered privacy, and request-side registry wiring.
  • Give the composite one marker source, consolidate final expiry logging, relay the latest Cloudflare timer waker, and share stateless adapter timer allocations.
  • Close harness stdin, preserve RUSTUP_TOOLCHAIN, publish readiness atomically, and gate Unix process tooling.
  • Refresh the public API errors, stable-capability contract, complete factory example, operator guidance, and scope documentation.
  • Merge current main in a separate commit and reconcile its toolchain, shared setup action, Viceroy and documentation changes.

API migration

Existing processors inherit default methods. Opted-in factories and sessions must declare matching lifetime-stable capabilities. Direct AuctionDispatch construction must pass the same integration_registry used for response processing. Publisher struct literals need both new fields or ..Publisher::default().

Validation

Fresh results on 423682810:

  • All 24 hosted CI checks pass, including integration, browser and Fastly EC lifecycle tests.
  • All 33 effective local Rust/build/doc checks pass: eight Clippy aliases, both WASM fixture feature checks, all adapter test aliases and Fastly reuse, native core (3,053 unit tests plus filesystem tests and doctests), digest lint, parity (18), guide snippets (2), EOF helpers (15), CLI/browser fixtures, codegen, integration checks, three debug builds, Fastly production build and core rustdoc.
  • Pinned Node 24.20.0: JS build and 1,211 Vitest tests pass; JS/docs/Markdown formatting, docs lint/build, wasm clock lint, proposal-script tests, changed-workflow actionlint and the shared Rust setup guard pass.
  • All 17 live runtime controls pass: Axum (4), Fastly/Viceroy 0.21.0 (5), Workers with matching worker-build/wasm-bindgen (4), and Spin 4.1.0 (4). Fastly emitted its first body byte at roughly 5 ms, before finalization completed.
  • Independent reviews of the complete core, adapter, harness, CI and documentation diff found no additional blocking defect. All 18 conversations from the detailed review have replies and are resolved.

Local sandbox certificate/socket restrictions and transient shared-target doctest metadata were resolved by permission/fresh-run retries; no source changes were needed for those runner issues. Runtime auction controls verify intentional empty-bid assembly, as described above.

Closes #1241.

@prk-Jr prk-Jr self-assigned this Oct 12, 2026
Comment thread scripts/fixtures/async-html-finalization-runtime.py Fixed
Comment thread scripts/fixtures/async-html-finalization-runtime.py Fixed
Comment thread scripts/fixtures/test_async_html_finalization_runtime.py Fixed
@prk-Jr prk-Jr changed the title Add optional asynchronous HTML document finalization Add opt-in ordered HTML processor EOF completion Oct 13, 2026
Comment thread scripts/fixtures/test_async_html_finalization_runtime.py Fixed
Comment thread scripts/fixtures/test_async_html_finalization_runtime.py Fixed
@prk-Jr
prk-Jr marked this pull request as ready for review October 14, 2026 12:33
@prk-Jr
prk-Jr marked this pull request as draft October 14, 2026 12:33
@prk-Jr
prk-Jr marked this pull request as ready for review October 15, 2026 09:40

@dhruv8sh dhruv8sh 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.

Summary

This PR adds opt-in, ordered async completion for HTML stream processors at document end. Operators must enable it with publisher.allow_async_html_finish, it shares one deadline, and it keeps the synchronous output if a stage fails, times out or overflows. It also adds timer wiring for Axum, Workers and Spin and a bounded auction suffix. I found no correctness bugs in the runtime path: routing on all four adapters, auction abandonment on init, partial-response and write errors, push_bounded boundary handling, deadline and timer sharing, and the retention overflow replay all check out. The one blocking item is a scope question: this PR turns off shared-template caching where issue #1241 asked for cold-miss support, but its description still says "Closes #1241".

1 of the inline comments below carries a one-click GitHub suggestion. Use Commit suggestion to apply it as a commit on the PR branch. The remaining comments describe the fix in prose because it touches multiple files or lines outside the diff, so it can't be auto-applied.

Blocking

❓ question

  • Shared-template caching is disabled, but the PR says "Closes #1241": see inline at crates/trusted-server-core/src/publisher.rs:5108

Non-blocking

🤔 thinking

  • The guide's KV example blocks without limit on Fastly: see inline at docs/guide/integration-guide.md:256
  • New AGENTS.md gates 11 to 13 would apply to every PR: see inline at AGENTS.md:369

♻️ refactor

  • Test-only adapter keeps an older API's names alive: see inline at crates/trusted-server-core/src/integrations/html_finalization.rs:1

📝 note

  • The bundled from_toml_and_env fix duplicates open PR #1326: see inline at crates/trusted-server-core/src/settings.rs:3083

⛏ nitpick

  • mod html_finalization; sits between two use lines (suggestion): see inline at crates/trusted-server-core/src/publisher.rs:23
  • Test placed above the module's imports: see inline at crates/trusted-server-adapter-axum/src/platform.rs:612
  • Unrelated quote-style churn: see inline at .github/workflows/test.yml:1

📌 out of scope

  • CI now uses two Viceroy versions (0.19 and the pinned 0.17): see inline at .github/workflows/test.yml:74

👍 praise

  • Poisoning replacement writer: see inline at crates/trusted-server-core/src/streaming_processor/finish.rs:88
  • Missing permission fails at startup: see inline at crates/trusted-server-core/src/integrations/registry.rs:1146
  • Boundary-aware marker counting: see inline at crates/trusted-server-core/src/html_processor/finish.rs:142

CI Status

  • browser integration tests: PASS
  • integration tests: PASS
  • integration tests (Fastly EC lifecycle): PASS
  • CodeQL: PASS
  • cargo test (ts CLI, native) (macos-latest): PASS
  • format-docs: PASS (required)
  • CLAUDE.md symlink guard: PASS
  • Analyze (actions): PASS
  • vitest: PASS
  • cargo fmt: PASS (required)
  • HTML EOF runtime (Fastly): PASS
  • cargo test: PASS (required)
  • format-typescript: PASS (required)
  • cargo test (ts CLI, native) (ubuntu-latest): PASS
  • Analyze (javascript-typescript): PASS
  • cargo check/build/test (spin native + wasm32-wasip1): PASS
  • cargo check (cloudflare native + wasm32-unknown-unknown): PASS
  • cargo test (cross-adapter parity): PASS
  • cargo test (axum native): PASS
  • prepare integration artifacts: PASS
  • Analyze (python): PASS
  • Analyze (rust): PASS

Comment thread crates/trusted-server-core/src/publisher.rs
Comment thread docs/guide/integration-guide.md
Comment thread AGENTS.md Outdated
Comment thread .github/workflows/test.yml
Comment thread crates/trusted-server-core/src/integrations/html_finalization.rs Outdated
Comment thread crates/trusted-server-adapter-axum/src/platform.rs
Comment thread .github/workflows/test.yml Outdated
Comment thread crates/trusted-server-core/src/streaming_processor/finish.rs
Comment thread crates/trusted-server-core/src/integrations/registry.rs
Comment thread crates/trusted-server-core/src/html_processor/finish.rs
@prk-Jr
prk-Jr requested a review from dhruv8sh October 15, 2026 14:14

@ChristianPavilonis ChristianPavilonis 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.

Review summary

Reviewed opt-in ordered HTML EOF completion across correctness, architecture, code-smell and style lanes. No verified correctness, architecture or style defects were found. The inline finding is low-priority, non-blocking maintenance feedback, not a demonstrated behavioral defect.

The full review covered a0b00c7..912767c. The subsequent commit 7f1c678 changes only cache documentation; the inline finding was revalidated against that head.

Validation passed: 37 core EOF regressions, 19 finalization tests, 394 publisher tests, 14 runtime-harness helper tests, 18 host-parity tests and 2 documentation fixtures. Counts overlap across filtered core suites. Formatting, whitespace, clock lint, workflow, shell, Markdown and TOML checks also passed. Actual external runtimes and the full CI matrix were not rerun in this review.

Comment thread crates/trusted-server-core/src/streaming_processor/finish.rs Outdated

@dhruv8sh dhruv8sh 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.

Summary

This pass covers the six commits since my last review (142a839d9..7f1c67875), plus a fresh read of the EOF runtime path. Every earlier finding is addressed. I found no new correctness, WASM-compatibility or convention problems. On the scope question, I accept the narrower scope with "Closes #1241" kept: shared-template caching for async output is tracked in #1397, and the configuration guide now warns that enabling async finish disables template caching.

1 of the inline comments below carries a one-click GitHub suggestion. Use Commit suggestion to apply it as a commit on the PR branch. The other inline comment is a future-facing note with no change requested in this PR.

Non-blocking

⛏ nitpick

  • use finish::... splits the external-crate import group (suggestion): see inline at crates/trusted-server-core/src/streaming_processor.rs:36

🌱 seedling

  • Integrations outside core can't unit-test async_finish: see inline at crates/trusted-server-core/src/streaming_processor/finish.rs:68

Cross-cutting / body-level findings

  • 👍 Every earlier finding was addressed cleanly. The fixtures migrated off the removed test-only adapter declare the same capabilities it did (requires_async_finish() = true, buffer_output_until_eof() = true), so the regression tests keep their semantics. The guide example now skips its KV lookup when no cooperative timer exists, with the Fastly warning next to the snippet. The EOF checks are scoped in AGENTS.md, the duplicated from_toml_and_env hunk is gone, the workflow quote churn is reverted, and the docs now warn about the template-cache bypass and link #1397.
  • 🤔 The two range-associated HTML copy paths cap bytes differently (low priority). The sync stream_publisher_body copies range-associated HTML with an uncapped std::io::copy (crates/trusted-server-core/src/publisher.rs:3046-3051). stream_publisher_body_async copies through BodyChunkSource::with_max_bytes(max_buffered_body_bytes) (publisher.rs:3214-3229), so a 206 HTML response larger than the cap fails partway through. The in-tree adapters don't reach the async copy, because the buffered and Fastly streaming entry points return the raw body before it, so only direct library callers are affected. Consider either dropping the cap on the async pass-through or adding one to the sync path, whichever you intend. This needs a manual change: the two sites are in different hunks, so a single suggestion can't cover both.

CI Status

  • integration tests (Fastly EC lifecycle): PASS
  • integration tests: PASS
  • browser integration tests: PASS
  • CodeQL: PASS
  • cargo test (ts CLI, native) (macos-latest): PASS
  • format-docs: PASS (required)
  • CLAUDE.md symlink guard: PASS
  • Analyze (rust): PASS
  • Analyze (actions): PASS
  • cargo fmt: PASS (required)
  • HTML EOF runtime (Fastly): PASS
  • cargo test: PASS (required)
  • format-typescript: PASS (required)
  • vitest: PASS
  • Analyze (javascript-typescript): PASS
  • prepare integration artifacts: PASS
  • cargo check (cloudflare native + wasm32-unknown-unknown): PASS
  • cargo test (cross-adapter parity): PASS
  • cargo check/build/test (spin native + wasm32-wasip1): PASS
  • cargo test (ts CLI, native) (ubuntu-latest): PASS
  • cargo test (axum native): PASS
  • Analyze (javascript-typescript): PASS
  • Analyze (python): PASS

Comment thread crates/trusted-server-core/src/streaming_processor.rs Outdated
Comment thread crates/trusted-server-core/src/streaming_processor/finish.rs

@ChristianPavilonis ChristianPavilonis 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.

Approved. The opt-in ordered EOF completion adds explicit operator permission, bounded fallback handling, and shared deadlines while keeping chunk processing synchronous. No additional comments.

@aram356 aram356 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.

Summary

This PR adds opt-in, ordered async completion for HTML stream processors at document EOF, with operator permission, one shared deadline and bounded fallback. Under probing and mutation testing, the processor lifecycle holds up: one EOF per stage, ordered downstream delivery, deadline ties, candidate poisoning, overflow replay, push_bounded (checked against the old unbounded push on 20,000 random chunkings), and no new work on the no-hook path. Three things block:

  • A proven config-blob compatibility break.
  • A proven cap bypass on the lazy finalizer for materialized bodies.
  • A rebase onto main that needs more than conflict resolution.

10 of the inline comments below carry a one-click GitHub suggestion. Use Commit suggestion (or Add suggestion to batch for several at once) to apply them as commits on the PR branch. Each one was applied verbatim at f5ec39ca7 and checked, individually and as a batch: fmt, all six clippy aliases, test-fastly/axum/cloudflare/spin and parity for the Rust ones; the harness helper tests and clippy for the harness ones; prettier for the docs ones. The remaining comments describe the fix in prose because it spans several hunks or files, or adds tests outside the diff.

Blocking

🔧 wrench

  • New Publisher fields break config rollout and rollback (suggestion): see inline at crates/trusted-server-core/src/settings.rs:99
  • Lazy finalizer skips the raw-size and decode caps for materialized bodies: see inline at crates/trusted-server-core/src/publisher/html_finalization.rs:132
  • Rebasing onto main needs more than conflict resolution: see Cross-cutting below

Non-blocking

♻️ refactor

  • Parity test can't catch a wrong AuctionDispatch::integration_registry: see inline at crates/trusted-server-integration-tests/tests/parity.rs:1209
  • Pre-callback flush barrier has no test (M2 survives), plus two more survivors: see inline at crates/trusted-server-core/src/publisher/html_finalization.rs:327
  • Composite synchronous-EOF guard has no test (M1 survives): see inline at crates/trusted-server-core/src/html_processor.rs:45
  • Document that requires_async_finish must not change (suggestion): see inline at crates/trusted-server-core/src/streaming_processor.rs:58
  • The "auction" runtime control never completes a bid round trip: see inline at crates/trusted-server-integration-tests/tests/html_eof_runtime.rs:713

🌱 seedling

  • worker::Delay only wakes its first waker: see inline at crates/trusted-server-adapter-cloudflare/src/platform.rs:768

🤔 thinking

  • The same range bypass reports two abandon reasons: see inline at crates/trusted-server-core/src/publisher.rs:2657
  • The timeout reads as a hard limit on Fastly (suggestion): see inline at docs/guide/configuration.md:475

📝 note

  • Stale draft and scope lines in the spec and plan (suggestion): see inline at docs/superpowers/specs/2026-10-12-1241-async-html-finalization-design.md:177
  • Rustdoc on the async entry points wasn't updated: see inline at crates/trusted-server-core/src/publisher.rs:3212

⛏ nitpick

  • max_buffered_body_bytes purpose lost its specifics (suggestion): see inline at docs/guide/configuration.md:488
  • Hand-packed try_stream! body (suggestion): see inline at crates/trusted-server-core/src/publisher.rs:2687
  • Non-atomic owner.ready write (suggestion): see inline at crates/trusted-server-integration-tests/tests/html_eof_runtime/process.rs:434
  • RUSTUP_TOOLCHAIN is dropped (suggestion): see inline at crates/trusted-server-integration-tests/tests/html_eof_runtime/process.rs:32
  • Vacuous test (suggestion): see inline at crates/trusted-server-core/src/streaming_processor/finish.rs:206
  • 1..60000 reads as exclusive (suggestion): see inline at trusted-server.example.toml:74

Cross-cutting / body-level findings

  • 🔧 Rebasing onto main needs more than conflict resolution. main is now at f9281917a, and this PR conflicts in .github/workflows/test.yml and scripts/README.md. The Rust side of the merge is clean: the merged tree's native core suite passes 3045/3045. Two other main changes also affect this PR:
    • #1259 guard. It added "Require the shared Rust setup action" to the required cargo fmt job. The new test-fastly-eof job calls actions-rust-lang/setup-rust-toolchain@v1 directly (line 90 of the merged file), so that required check fails after a plain conflict resolution.
      • Set the job up with uses: ./.github/actions/setup-rust and its own cache-key (for example cargo-fastly-eof).
      • Move test-axum's components: clippy into that action's with:.
    • #1123 Viceroy pin. main now pins Viceroy 0.21.0 in .tool-versions, which meets the harness's >= 0.19 floor.
      • Drop the curl, sha256, cache and $GITHUB_PATH steps for the separate 0.19 download, and reuse test-rust's cached .tool-versions install. This also closes the earlier dual-Viceroy follow-up.
      • Rewrite the "isolated Viceroy 0.19" and "ordinary tests retain 0.17" text in AGENTS.md:373 (line 382 after the merge), docs/guide/testing.md:64-71, scripts/README.md:19,34-41, and plan lines 54, 73 and 100.
      • Keep validate_viceroy's 0.19 floor; it states the real capability requirement.
  • 📝 Some PR description rows are stale.
    • "test-only legacy loader excludes merged build-version metadata": the change was dropped in 6eda72c.
    • "compatibility fake callbacks are crate-private and test-only": that module was deleted.
    • "Core auction telemetry": no auction file is in the net diff against main.
    • "remove … execution histories": see the plan comment.
    • "isolated cached Viceroy 0.19 … ordinary 0.17 test pin": changes with the rebase.
  • ⛏ Harness and CI.
    • Set command.stdin(Stdio::null()) in ManagedChild::spawn, so a child that touches the TTY can't stop on SIGTTIN/SIGTTOU in its background process group.
    • The cfg(not(unix)) arms in process.rs can't compile, because libc has no Windows SIGKILL. #![cfg(unix)] on the test target is simpler and matches the spec.
    • The test-axum helper and clippy steps omit --target while the script passes it, so the integration-test graph compiles twice.
    • No CI job compiles the Cloudflare and Spin test-utils FixtureLogger code. clippy -p trusted-server-adapter-cloudflare --target wasm32-unknown-unknown --features cloudflare,test-utils --lib and clippy -p trusted-server-adapter-spin --target wasm32-wasip1 --features spin,test-utils --lib both pass today and would keep it from rotting.
    • docs/guide/testing.md and scripts/README.md say SIGTERM, but the harness also handles SIGINT.
  • ⛏ Core.
    • The finish marker has two sources of truth: set_finish_marker stores only its length, while the bytes come from HtmlFinishContext.marker. Storing the bytes once avoids a caller passing one without the other.
    • The post-completion expiry checks at html_processor/finish.rs:218 and :252 overlap (removing the first survives), and the :252 path returns the fallback without logging. Merge them into one final check that keeps the timeout warn!.
    • Removing the retained.is_some() && !async_capable clause from validate breaks no test.
    • HtmlWithStreamingProcessors returns true from requires_async_finish but keeps the default async_finish, so it can only be driven through begin_finish/finish_next. A line of doc on that impl would help.
    • Two test names claim more than they check: terminal_document_state_observes_parser_callbacks_and_isolates_requests (the test builds a fresh state per loop iteration itself) and Axum's html_finalization_timer_is_request_scoped (it only asserts the timer is present).
  • ⛏ Publisher.
    • encode_processed_html takes Option<&mut AuctionHoldState>, but its only caller passes Some, so the None branch is dead.
    • HtmlEofDriver::accept takes is_last, but its only caller passes false.
  • ⛏ Docs.
    • The guide example omits the factory, although a factory/session capability mismatch fails the request. A short ExampleFooterFactory with requires_async_finish() -> true would complete it, and documentation_snippets would keep compiling it.
    • allow_async_html_finish could say that no built-in integration declares async completion yet, so the setting has no effect in a stock build.
  • ⛏ Adapters. Each adapter allocates a new timer Arc per request, including on no-hook pages. A OnceLock like the neighbouring GEO and config-store statics avoids it.

CI Status

All checks pass at f5ec39ca7. The PR is now CONFLICTING with main, so these results predate the rebase.

  • Analyze (actions): PASS
  • Analyze (javascript-typescript): PASS
  • Analyze (python): PASS
  • Analyze (rust): PASS
  • browser integration tests: PASS
  • cargo check (cloudflare native + wasm32-unknown-unknown): PASS
  • cargo check/build/test (spin native + wasm32-wasip1): PASS
  • cargo fmt: PASS (required)
  • cargo test: PASS (required)
  • cargo test (axum native): PASS
  • cargo test (cross-adapter parity): PASS
  • cargo test (ts CLI, native) (macos-latest): PASS
  • cargo test (ts CLI, native) (ubuntu-latest): PASS
  • CLAUDE.md symlink guard: PASS
  • CodeQL: PASS
  • format-docs: PASS (required)
  • format-typescript: PASS (required)
  • HTML EOF runtime (Fastly): PASS
  • integration tests: PASS
  • integration tests (Fastly EC lifecycle): PASS
  • prepare integration artifacts: PASS
  • vitest: PASS

Comment thread crates/trusted-server-core/src/settings.rs
Comment thread crates/trusted-server-core/src/publisher/html_finalization.rs Outdated
Comment thread crates/trusted-server-integration-tests/tests/parity.rs
Comment thread crates/trusted-server-core/src/publisher/html_finalization.rs
Comment thread crates/trusted-server-core/src/html_processor.rs
Comment thread crates/trusted-server-integration-tests/tests/html_eof_runtime/process.rs Outdated
Comment thread crates/trusted-server-core/src/streaming_processor/finish.rs Outdated
Comment thread trusted-server.example.toml Outdated
Comment thread crates/trusted-server-core/src/publisher.rs
Comment on lines +130 to +140
fn signal_group(id: u32, signal: i32) {
#[cfg(unix)]
if let Ok(id) = libc::pid_t::try_from(id) {
// Every registered ID belongs to a child started in its own process group.
unsafe {
libc::killpg(id, signal);
}
}
#[cfg(not(unix))]
let _ = (id, signal);
}

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.

⛏ nitpick: The test target is now #![cfg(unix)], so the cfg(not(unix)) arms in this file can no longer compile, and the #[cfg(unix)] guards next to them are redundant. This drops the pair in signal_group:

Suggested change
fn signal_group(id: u32, signal: i32) {
#[cfg(unix)]
if let Ok(id) = libc::pid_t::try_from(id) {
// Every registered ID belongs to a child started in its own process group.
unsafe {
libc::killpg(id, signal);
}
}
#[cfg(not(unix))]
let _ = (id, signal);
}
fn signal_group(id: u32, signal: i32) {
if let Ok(id) = libc::pid_t::try_from(id) {
// Every registered ID belongs to a child started in its own process group.
unsafe {
libc::killpg(id, signal);
}
}
}

The same cleanup applies to the #[cfg(not(unix))] block at lines 120-125, the #[cfg(not(unix))] self.child.kill() at lines 189-190, and the #[cfg(unix)] on command.process_group(0) at line 150.

Verified with this applied: rustfmt, the 15 harness helper tests and harness clippy pass.

This branch has not been deployed

No deployments
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.

Let an HTML stream processor await I/O when the document ends

4 participants