Skip to content

Rust #325: describe parents with several open children - #865

Merged
rmcdaniel merged 1 commit into
mainfrom
rust-325-child-descriptions
Oct 29, 2026
Merged

rmcdaniel merged 1 commit into
mainfrom
rust-325-child-descriptions

Conversation

@rmcdaniel

Copy link
Copy Markdown
Member

Part of #325.

What changed

Native now describes a parent by its open waits however many children it holds, as published PHP 2.11.5 does.

  • Before: native's child summary (child_summary.rs) gave up, leaving wait_kind null, when:
    • a second child was open while another still waited;
    • a child's parent_close_policy was not abandon;
    • more than 100 children had been started over the run's life;
    • a timer wait was also open.
  • Contract (published PHP RunWaitView):
    • with several open children, the parent waits for the first;
    • an open timer is described ahead of open children, whichever was scheduled first;
    • the parent-close policy does not change the description.
  • Native:
    • the summary keeps any number of open children, with no lifetime cap;
    • any parent-close policy is allowed;
    • an already chosen timer wait stays the run's wait while every child is open.

Evidence

  • New fixture child-descriptions (raw worker HTTP on protocol 1.20), five cases: one child, two children, child then timer, timer then child, and a child with parent_close_policy: terminate. Each records the completion answer and the parent's description. After recording, the probe terminates the children and then the parent, so their never-polled tasks don't load PHP's maintenance loop for later fixtures (see Rust #325: accept completions and parallel groups over 100 #851).
  • Recorded locally at this head: published 2.11.5 and native (an image built from it) both pass.
  • Tests: rust/tests/execution/child_descriptions.rs covers the five cases. On the previous source, two children and a child beside a timer were described with a null wait.
  • Full native suites, run locally: execution 634 passed, lib 359 passed. Node unit tests pass (361).

Not covered

A child with a cancellation policy other than abandon, a retry or timeout policy, or beside an open activity, is still described without its wait. Each needs its own evidence first.

🤖 Generated with Claude Code

Published PHP describes a parent by its open waits however many
children it holds: the first open child, or an open timer ahead of open
children, under any parent-close policy. Native's child summary allowed
one waiting child at a time, only the abandon parent-close policy, at
most 100 children over a run's life, and no timer beside a child, so
such a parent was described with no wait. Lift those limits, and keep
an already chosen timer wait while every child is open.

The new child-descriptions fixture records five cases against published
2.11.5. A child with another cancellation, retry or timeout policy, or
beside an open activity, stays unqualified pending its own evidence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sonarqubecloud

Copy link
Copy Markdown

@rmcdaniel

Copy link
Copy Markdown
Member Author

Cloud static review of c2cdbaf9d9213e74305f9122b74a0c639be17575 (tree 90f7a8a2aaba7748143655a3a8aaa49e232fc2d7, parent bcad719963e5ba58c5024b5554f3c25b8ca3b51f): no blocking correctness finding in the changed implementation.

All children still pass typed-history identity and wait/call/link-row validation before the new timer-preservation branch. Duplicate sequence/child identities and the existing cancellation/retry/timeout restrictions remain. Both lifetime-100 restrictions are removed: history admission and the SQL limit/row-count guard. Open-child selection remains ordered by sequence.

I traced the contract through published Server2.11.5's locked Core2.15.1 source 07e0d0e1a1185bd0a3bbd4e3fb56511cc57ca9bc. Its summary projector suppresses child selection when an authoritative open timer exists, then selects the first eligible child from sorted known sequences. That supports the changed precedence and ordering.

The fixture comparator checks the complete recorded completion result and selected description fields for all five cases, rejects extra/missing cases, and explicitly marks embedded mode inapplicable. The probe terminates children before the parent after recording. Coverage limits: the five new cases do not exercise the >100 lifetime boundary or distinguish two different child labels. The cap removal and ordered selection above are implementation-review evidence, not additional fixture observations.

This was a static source/fixture review. I ran no Rust or HTTP workload; the locally reported native/published-reference suites remain the owner's evidence. Normal hosted checks and combined-source qualification remain required. This review authorizes no Native publication and does not change the separate #861 reference hold.

@rmcdaniel

Copy link
Copy Markdown
Member Author

PR CI run 40905860198: one lane failed, and not on this PR's fixture. The SQLite execution-and-codec corpus excerpt reads update-validation (product-fail): update validation worker_lost waited for the validation timeout (0.0526 seconds) on the published PHP target. Published PHP answered the "worker lost" step at once instead of after the validation timeout.

That fixture uses its own namespace and is untouched here. Locally, published 2.11.5 passes child-descriptions followed by update-validation in one record. Every other lane, including the MySQL and PostgreSQL corpora, passed. I'm treating it as a PHP timing flake. #864 has queue priority, so I'll rerun the failed job after #864 merges rather than now.

@rmcdaniel

Copy link
Copy Markdown
Member Author

General's read-only PHP helper review found a candidate timing-measurement defect, not yet a proven cause of this failed run.

Original attempt 1, corpus job reports update-validation / worker_lost at 0.052609920501708984 seconds, against the unchanged 9–20-second validation bounds. In update-validation-probe.php at this PR head, the background update helper assigns $started = microtime(true) inside its bounded lock-pressure retry loop, then reports microtime(true) - $started after the loop. It therefore measures only the final HTTP attempt.

If an initial validation request actually waits to its deadline but requires a lock-pressure retry, a final request returning the retained receipt quickly can be reported as approximately 0.05 seconds. The correct witness for the existing timeout contract is the entire logical request, including its existing bounded retries. The original hosted log does not establish that exact retry/receipt sequence, so I am not attributing this run to that mechanism yet; its original record/retry notes are still needed for correlation.

A focused helper correction should cover an initial waiting response followed by a fast retained receipt, plus an immediate no-retry response, preserving the frozen 9–20-second bounds, assertions and Server behavior. No shared fixture or source has been edited by this review. A passing rerun alone will not resolve the candidate measurement defect.

@rmcdaniel
rmcdaniel added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 48652c9 Oct 29, 2026
98 of 100 checks passed
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.

1 participant