Repository navigation
Conversation
The per-execution cleanup removed every execution.<event>.<id> listener except execution.run_collection_request.<id>, registered for every script since 7.46.0. One listener and its closure stayed on the host per script run until the run ended. Co-Authored-By: Claude <[email protected]>
Codecov Report✅ All modified and coverable lines are covered by tests. ❌ Your project check has failed because the head coverage (34.33%) is below the target coverage (35.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## develop #1566 +/- ##
========================================
Coverage 77.54% 77.55%
========================================
Files 51 51
Lines 4338 4339 +1
Branches 1223 1223
========================================
+ Hits 3364 3365 +1
Misses 731 731
Partials 243 243
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Measured before/after on a real workload. This was a copy of the PPC Governor collection (AUTO-1062) run through
Per request name, the counts and the pass/fail of every assertion are identical. The one exception is the last loop, which runs until time is up and so follows throughput. Reviewer guide covering all the AUTO-1062 changes, with before/after code and results: https://claude.ai/artifact/S7vBMoFxTA9kjzQHhQTXpt |
Context
Each script execution registers an
execution.run_collection_request.<executionId>listener on the sandbox host (lib/runner/extensions/event.command.js:728). It was added in 7.46.0 withpm.execution.runRequest(#1522), and it is registered whether or not the script callspm.execution.runRequest. The per-execution cleanup in thehost.executecallback removes the other tenexecution.<event>.<id>listeners, but not this one. So one listener and its closure stay on the host for every script run until the run ends.In a 44-VU perf run (about 105 rps, about 1.8 scripts per request), a heap snapshot at 900 s showed 173,356 of these listeners in the host's
_events. It was the largest single object in the heap: about 330 B of live memory per script run (+41 MB over 11 min). With this line patched in, the VU thread's live heap stayed flat (135.6 → 136.0 MB over 660 s).Summary of the change
this.host.removeAllListeners(EXECUTION_RUN_REQUEST_EVENT_BASE + executionId)to the per-execution cleanup, next to the other removals. This is safe because the sandbox dispatches eachpm.execution.runRequestcall before it dispatches the execution result, and bridge events arrive in order. The matchingexecution.run_collection_request_response.<id>listener is already removed at the same point.test/unit/event-command-listener-cleanup.test.js: it runs two prerequest scripts on a stub host and checks that no listener keyed by either execution id is left on the host.Breaking changes
None.
Dependencies
None.
Test plan
npx mocha test/unit/event-command-listener-cleanup.test.js: fails without the fix (expected [ …(2) ] to deeply equal [], one leaked listener per execution) and passes with it.npm run test-unit: 572 passing, 10 pending.Generated with Claude Code