fix(plugin): drop scope-close deregistration of shutdown hooks#76
Merged
Conversation
Fix 3 from the cubic review on PR #75 was a regression. The plugin-layer scope (under InstanceState) closes BEFORE the top-level finally in src/index.ts runs, via store.dispose(ctx) in effect-cmd's own finally. A scope-close finalizer empties pluginShutdownHooks before the host can iterate it, defeating the entire feature. Verified live: v0.1.8-rc1 in staging cloud V4 still produced orphan turn parents (trace 0ee0b31c-..., top_span_landed=False, total_cost=0, all session.llm children referencing one unlanded parent span). Multi-instance TUI mode bloat from accumulated closures is acceptable -- rare in practice, closures are tiny, and the hooks Set is intentionally module-level so it outlives Effect scopes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Drop the
Effect.addFinalizerthat deregisters plugin shutdown hooks onInstanceStatescope close. Fix 3 from the cubic review on PR #75 was a lifecycle regression.Why
Verified on staging V4 after PR #75 shipped as
v0.1.8-rc1: trace0ee0b31c-4970-c840-be54-d7bf5da53b37from a real cloud bcode run still has the exact same problem PR #75 was supposed to fix —top_span_landed=False,total_cost=0, allsession.llmchildren point to one orphan parent (the bcode-laminar "turn" span) that never landed.The synchronous shutdown hook from PR #75 was never being invoked. Root cause is the lifecycle, not the hook itself:
So the turn span never gets
.end()'d, never gets queued for export, and the top-levelforceFlush(3000ms)drains nothing useful.pluginShutdownHooksis intentionally module-level — that's the entire point: the Set must outlive the Effect scopes so the host can reach it from outside the runtime. A scope-close finalizer defeats that.Fix
Just drop the
Effect.addFinalizer. Multi-instance TUI bloat (the cubic reviewer's concern) is the lesser evil: rare in practice, closures are tiny, and the cost is bounded by the number of instances opened over a TUI session lifetime. Comment block updated so the next reviewer doesn't re-add the dereregistration.Diff
Verification plan
v0.1.8-rc2→ bump cloud staging Dockerfile to rc2.top_span_landed=Truefor the bcode-laminar turn parent andtotal_cost > 0on the trace aggregate.v0.1.8proper, then bump prod.Refs
v0.1.8-rc1verification trace:0ee0b31c-4970-c840-be54-d7bf5da53b37EXCEPTIONS.mdupdated with the lifecycle analysis under the existing PR fix(plugin): synchronous shutdown hook for OTel span drain (revert PR #74) #75 section.Summary by cubic
Stop deregistering plugin shutdown hooks on scope close so they survive
InstanceStateteardown and run at process exit. This fixes orphan spans and ensures telemetry flushes correctly.Effect.addFinalizerthat deleted hooks on scope close.pluginShutdownHooksuntil the top-levelfinallyexecutes them.v0.1.8-rc1.Written for commit adfa914. Summary will update on new commits. Review in cubic