Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
This comment has been minimized.
This comment has been minimized.
🟢 Java Benchmark SLOs — All performance SLOs passed
PR vs. master results
Commit: Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion. |
1b00f2e to
c9c419d
Compare
c9c419d to
188f30f
Compare
|
(Comment drafted by Claude on behalf of @dougqh.) I checked the fix against the 2.13.17 source, and the mechanism is correct: Reward. As far as I can tell, this fixes a flaky test timeout, and the leak looks like a delayed trace flush rather than lost or incorrect data. Risk. This is ASM surgery on a private method of the Scala stdlib. It depends on the call-site count ( Two questions:
I'm not blocking. I'd just like us to decide deliberately that the reward justifies this kind of instrumentation. |
|
Thanks for the thourough review @dougqh I’ve added independent guards for the exact CAS count and preservation of the callback argument, plus mutation tests for violations. The remaining tradeoff is explicit: an unsupported bytecode shape rejects the whole Datadog transformation for DefaultPromise, including its other advice. DefaultPromise instrumentation also, is opt-in.
The diagnostic is there to highlight this kind of lifecycle misses. Now we can ignore it if it's too complex to maintain. The diagnostic allows to override the check by providing a reason.
Yes I already did this in the PR as suggested. |
What Does This Do
Fixes a continuation leak in Scala 2.13.17+ when
Future.firstCompletedOfunregisters callbacks from futures that did not complete first.The instrumentation releases a callback’s continuation only when Scala’s callback-removal CAS succeeds. If completion has already dispatched the callback, ownership remains with the callback until it runs.
flowchart LR A[Capture callback continuation] --> B{Which operation wins?} B -->|Unregister CAS| C[Release continuation] B -->|Callback dispatch| D[Callback run consumes continuation]Motivation
GitLab job
2087926766intermittently timed out in:ScalaInstrumentationTest > scala first completed futureDiagnostics identified an unresolved continuation captured by
Promise$Transformation. Scala 2.13.17 introduced callback unregistration forfirstCompletedOf, adding a terminal lifecycle path that bypassed the existing execution cleanup.Unconditional cleanup on
unregisterCallbackwould be unsafe because completion can commit the callback to execution before unregistration observes the promise state. The successful removal CAS is the point where ownership is transferred safely.Motivation
Additional Notes
Contributor Checklist
type:and (comp:orinst:) labels in addition to any other useful labelsclose,fix, or any linking keywords when referencing an issueUse
solvesinstead, and assign the PR milestone to the issueJira ticket: [PROJ-IDENT]