Skip to content

fix(coverage): document RPC error codes 105/106 and memoize test hitmap process - #2452

Open
kevmoo wants to merge 1 commit into
mainfrom
fix_ci_infra
Open

fix(coverage): document RPC error codes 105/106 and memoize test hitmap process#2452
kevmoo wants to merge 1 commit into
mainfrom
fix_ci_infra

Conversation

@kevmoo

@kevmoo kevmoo commented Jul 2, 2026

Copy link
Copy Markdown
Member

Summary

  • Document RPC error codes 105 (IsolateExited) and 106 (IsolateMustBePaused) in isolate_paused_listener.dart.
  • Memoize _getHitMap() in lcov_test.dart to avoid spawning 17+ separate Dart processes during test runs, reducing test execution time from 2.5 minutes to 8 seconds.

@kevmoo
kevmoo requested review from a team and liamappelbe as code owners July 2, 2026 06:02
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Package publishing

If you have publishing permissions, you can use the links below to publish the changes after merging this PR.

Package Version Status Publish tag (post-merge)
package:api_summary 0.1.0-wip WIP (no publish necessary)
package:bazel_worker 1.1.5 already published at pub.dev
package:benchmark_harness 2.4.0 already published at pub.dev
package:boolean_selector 2.1.2 already published at pub.dev
package:browser_launcher 1.2.0-wip WIP (no publish necessary)
package:cli_config 0.2.1-wip WIP (no publish necessary)
package:cli_util 0.5.1 already published at pub.dev
package:clock 1.1.3-wip WIP (no publish necessary)
package:code_builder 4.12.0-wip WIP (no publish necessary)
package:coverage 1.15.1 already published at pub.dev
package:csslib 1.0.2 already published at pub.dev
package:extension_discovery 2.1.0 already published at pub.dev
package:file 7.0.2-wip WIP (no publish necessary)
package:file_testing 3.1.0-wip WIP (no publish necessary)
package:glob 2.1.3 already published at pub.dev
package:graphs 2.4.0-wip WIP (no publish necessary)
package:html 0.15.7-wip WIP (no publish necessary)
package:io 1.1.0-wip WIP (no publish necessary)
package:json_rpc_2 4.1.0 already published at pub.dev
package:markdown 7.4.0 ready to publish markdown-v7.4.0
package:mime 2.1.0-wip WIP (no publish necessary)
package:oauth2 2.0.5 already published at pub.dev
package:package_config 3.0.0 already published at pub.dev
package:pool 1.5.3-wip WIP (no publish necessary)
package:process 5.0.5 (error) pubspec version (5.0.5) and changelog (5.0.6-wip) don't agree
package:pub_semver 2.2.0 already published at pub.dev
package:pubspec_parse 1.6.0-wip WIP (no publish necessary)
package:source_map_stack_trace 2.1.3-wip WIP (no publish necessary)
package:source_maps 0.10.14-wip WIP (no publish necessary)
package:source_span 1.10.2 already published at pub.dev
package:sse 4.2.1-wip WIP (no publish necessary)
package:stack_trace 1.12.2-wip (error) pubspec version (1.12.2-wip) and changelog (1.12.2-dev) don't agree
package:stream_channel 2.1.4 already published at pub.dev
package:stream_transform 2.1.2-wip WIP (no publish necessary)
package:string_scanner 1.4.2-wip WIP (no publish necessary)
package:term_glyph 1.2.3-wip WIP (no publish necessary)
package:test_reflective_loader 0.6.0 ready to publish test_reflective_loader-v0.6.0
package:timing 1.0.2 already published at pub.dev
package:unified_analytics 8.0.16-wip WIP (no publish necessary)
package:watcher 1.2.2-wip WIP (no publish necessary)
package:yaml 3.1.4-wip WIP (no publish necessary)
package:yaml_edit 2.2.4 already published at pub.dev

Documentation at https://github.com/dart-lang/ecosystem/wiki/Publishing-automation.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces error handling when resuming an isolate in IsolatePausedListener by catching and ignoring expected SentinelException and specific RPCError codes (105 and 106). Additionally, it optimizes lcov_test.dart by caching the hit map future to prevent redundant recreation. There are no review comments, so no feedback is provided.


Future<Map<String, HitMap>> _getHitMap() => _hitMapFuture ??= _createHitMap();

Future<Map<String, HitMap>> _createHitMap() async {

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Speeds up this test by many minutes!!

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

PR Health

Unused Dependencies ✔️
Package Status
coverage ✔️ All dependencies utilized correctly.

For details on how to fix these, see dependency_validator.

This check can be disabled by tagging the PR with skip-unused-dependencies-check.

Breaking changes ✔️
Package Change Current Version New Version Needed Version Looking good?
coverage None 1.15.1 1.15.1 1.15.1 ✔️

This check can be disabled by tagging the PR with skip-breaking-check.

API leaks ✔️

The following packages contain symbols visible in the public API, but not exported by the library. Export these symbols or remove them from your publicly visible API.

Package Leaked API symbol Leaking sources

This check can be disabled by tagging the PR with skip-leaking-check.

Coverage ✔️
File Coverage
pkgs/coverage/lib/src/isolate_paused_listener.dart 💚 98 % ⬆️ 0 %

This check for test coverage is informational (issues shown here will not fail the PR).

This check can be disabled by tagging the PR with skip-coverage-check.

License Headers ✔️
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

Files
no missing headers

All source files should start with a license header.

This check can be disabled by tagging the PR with skip-license-check.

// - 106: IsolateMustBePaused / CannotResume (isolate cannot be resumed)
const isolateExited = 105;
const isolateMustBePaused = 106;
if (e.code != isolateExited && e.code != isolateMustBePaused) {

@liamappelbe liamappelbe Jul 5, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's been a while since I've touched this code, but IIRC, I didn't want to ignore these exceptions because it usually means there's some sort of logical error in the (very complicated) isolate lifecycle management flow. Ignoring them turns them into harder to diagnose issues such as test processes just never terminating, or missing coverage data. I've used these exceptions several times to tighten up the lifecycle management.

Are you seeing this error in practice?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we see this error in practice during rapid isolate teardowns, especially when running high-concurrency coverage suites across platforms (like the incoming Web/Chrome coverage support where isolate lifecycles turn over quickly).

Here is the exact race condition:
IsolatePausedListener listens to VM service events asynchronously (_onStart, _onPause, _onExit) and backfills existing isolates from the event stream. During fast teardowns, an isolate frequently completes its work and exits right in the window after _onIsolatePaused(isolateRef, ...) finishes awaiting, but just before _service.resume(isolateRef.id!) is called.

When _service.resume executes on an isolate that just exited milliseconds prior, the VM service throws RPCError code 105 (IsolateExited) or 106 (IsolateMustBePaused / CannotResume), or SentinelException (isolate collected). If uncaught, these benign teardown race conditions crash the listener loop or cause unhandled exceptions during test_with_coverage teardown.

To make sure we don't mask real logical errors in lifecycle management, we explicitly filter for those specific error codes:

if (e.code != isolateExited && e.code != isolateMustBePaused) {
  rethrow;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Can you move the try/catch directly to the failing _service.resume call then?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, is this failure mode reproducible in a test?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants