Skip to content

Prepare IsolateManager to become source of truth for isPaused for an isolate. #5005

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jan 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ This page instructs how to contribute code changes to DevTools.
> If you just want to test newest functionality, follow
[beta testing guidance](https://github.com/flutter/devtools/blob/master/BETA_TESTING.md).

To contribute code you must complete the
Before contributing code:

1. Complete the
[Contributor License Agreement](https://cla.developers.google.com/clas).
You can do this online, and it only takes a minute. If you've never submitted code before,
you must add your (or your organization's) name and contact info to the [AUTHORS](AUTHORS)
file.
You can do this online, and it only takes a minute.

2. Understand [coding agreements](packages/README.md).

## Workflow for making changes

Expand Down
8 changes: 8 additions & 0 deletions packages/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Coding agreements in DevTools

We fully follow [Effective Dart](https://dart.dev/guides/language/effective-dart)
and some items of
[Style guide for Flutter repo](https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo):

## Order of getters and setters

When an object owns and exposes a (listenable) value,
Expand All @@ -10,3 +14,7 @@ in compliance with [Flutter repo style guide]( https://github.com/flutter/flutte
1. Public getter
2. Private field
3. Public setter (when needed)

## Naming for typedefs and function variables

Follow [Flutter repo naming rules for typedefs and function variables](https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#naming-rules-for-typedefs-and-function-variables).
13 changes: 7 additions & 6 deletions packages/devtools_app/lib/src/service/isolate_manager.dart
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ class IsolateManager extends Disposer {
final state = _isolateStates[isolateRef];
if (state != null) {
// Isolate might have already been closed.
state.onIsolateLoaded(isolate);
state.handleIsolateLoad(isolate);
}
}

Expand Down Expand Up @@ -249,14 +249,15 @@ class IsolateManager extends Disposer {
service.onDebugEvent.listen(_handleDebugEvent),
);

// We don't yet known the main isolate.
// We don't know the main isolate yet.
_mainIsolate.value = null;
}

Future<Isolate?> getIsolateCached(IsolateRef isolateRef) {
final isolateState =
_isolateStates.putIfAbsent(isolateRef, () => IsolateState(isolateRef));
return isolateState.isolate;
IsolateState isolateState(IsolateRef isolateRef) {
return _isolateStates.putIfAbsent(
isolateRef,
() => IsolateState(isolateRef),
);
}

void _handleDebugEvent(Event event) {
Expand Down
11 changes: 5 additions & 6 deletions packages/devtools_app/lib/src/service/isolate_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,22 @@ import 'package:vm_service/vm_service.dart' hide Error;
class IsolateState {
IsolateState(this.isolateRef);

ValueListenable<bool?> get isPaused => _isPaused;

final IsolateRef isolateRef;

/// Returns null if only this instance of [IsolateState] is disposed.
Future<Isolate?> get isolate => _completer.future;
Completer<Isolate?> _completer = Completer();

Isolate? get isolateNow => _isolateNow;
Isolate? _isolateNow;

/// Paused is null until we know whether the isolate is paused or not.
final _isPaused = ValueNotifier<bool?>(null);
ValueListenable<bool> get isPaused => _isPaused;
final _isPaused = ValueNotifier<bool>(false);

void onIsolateLoaded(Isolate isolate) {
void handleIsolateLoad(Isolate isolate) {
_isolateNow = isolate;
_completer.complete(isolate);
_isPaused.value ??= isolate.pauseEvent != null &&
_isPaused.value = isolate.pauseEvent != null &&
isolate.pauseEvent!.kind != EventKind.kResume;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,8 @@ class ServiceExtensionManager extends Disposer {
_checkForFirstFrameStarted = false;

final isolateRef = _isolateManager.mainIsolate.value!;
final Isolate? isolate = await _isolateManager.getIsolateCached(isolateRef);
final Isolate? isolate =
await _isolateManager.isolateState(isolateRef).isolate;

if (isolate == null) return;

Expand Down Expand Up @@ -316,7 +317,8 @@ class ServiceExtensionManager extends Disposer {

if (isolateRef != _mainIsolate) return;

final Isolate? isolate = await _isolateManager.getIsolateCached(isolateRef);
final Isolate? isolate =
await _isolateManager.isolateState(isolateRef).isolate;
if (isolateRef != _mainIsolate) return;

// Do not try to restore Dart IO extensions for a paused isolate.
Expand Down Expand Up @@ -400,7 +402,7 @@ class ServiceExtensionManager extends Disposer {

if (mainIsolate == null) return;
final Isolate? isolate =
await _isolateManager.getIsolateCached(mainIsolate);
await _isolateManager.isolateState(mainIsolate).isolate;
if (_isolateManager.mainIsolate.value != mainIsolate) return;

// Do not try to call Dart IO extensions for a paused isolate.
Expand Down Expand Up @@ -546,7 +548,7 @@ class ServiceExtensionManager extends Disposer {
if (mainIsolateRef != null) {
_checkForFirstFrameStarted = false;
final mainIsolate =
await _isolateManager.getIsolateCached(mainIsolateRef);
await _isolateManager.isolateState(mainIsolateRef).isolate;
if (mainIsolate != null)
await _registerMainIsolate(mainIsolate, mainIsolateRef);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ class ExpressionEvalFieldState extends State<ExpressionEvalField>

// Only try to eval if we are paused.
if (!serviceManager
.isolateManager.mainIsolateDebuggerState!.isPaused.value!) {
.isolateManager.mainIsolateDebuggerState!.isPaused.value) {
notificationService
.push('Application must be paused to support expression evaluation.');
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class EvalOnDartLibrary extends DisposableController

try {
final Isolate? isolate =
await serviceManager.isolateManager.getIsolateCached(isolateRef);
await serviceManager.isolateManager.isolateState(isolateRef).isolate;
if (_currentRequestId != requestId) {
// The initialize request is obsolete.
return;
Expand Down
2 changes: 1 addition & 1 deletion packages/devtools_test/lib/src/mocks/mocks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ class FakeVM extends Fake implements VM {

class MockIsolateState extends Mock implements IsolateState {
@override
ValueListenable<bool?> get isPaused => ValueNotifier<bool>(false);
ValueListenable<bool> get isPaused => ValueNotifier<bool>(false);
}

class MockIsolate extends Mock implements Isolate {}
Expand Down