[go: nahoru, domu]

Skip to content
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

Start reporting isolate life cycle events #5312

Closed
wants to merge 1 commit into from
Closed
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
22 changes: 13 additions & 9 deletions packages/flutter_tools/lib/src/hot.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ import 'cache.dart';
import 'commands/build_apk.dart';
import 'commands/install.dart';
import 'device.dart';
import 'globals.dart';
import 'devfs.dart';
import 'globals.dart';
import 'isolate_tracker.dart';
import 'observatory.dart';
import 'resident_runner.dart';

Expand Down Expand Up @@ -46,6 +47,7 @@ class HotRunner extends ResidentRunner {
ApplicationPackage _package;
String _mainPath;
String _projectRootPath;
IsolateTracker _isolateTracker;
final AssetBundle bundle = new AssetBundle();
final File pipe;

Expand Down Expand Up @@ -182,6 +184,8 @@ class HotRunner extends ResidentRunner {
observatoryPortCompleter.complete(result.observatoryPort);

await connectToServiceProtocol(result.observatoryPort);
_isolateTracker = new IsolateTracker(serviceProtocol);
await _isolateTracker.start();

if (device.needsDevFS) {
_loaderShowMessage('Connecting...', progress: 0);
Expand Down Expand Up @@ -305,17 +309,15 @@ class HotRunner extends ResidentRunner {
Completer<Null> completer = new Completer<Null>();
StreamSubscription<Event> subscription =
serviceProtocol.onIsolateEvent.listen((Event event) {
if (event.kind == 'IsolateStart') {
printTrace('Isolate is spawned.');
} else if (event.kind == 'IsolateRunnable') {
printTrace('Isolate is runnable.');
if (event.kind == 'IsolateRunnable') {
completer.complete(null);
}
});
await serviceProtocol.runInView(viewId,
entryPath,
packagesPath,
assetsDirectoryPath);
Response response = await serviceProtocol.runInView(viewId,
entryPath,
packagesPath,
assetsDirectoryPath);
_isolateTracker.viewIsolateId = response.response['isolateId'];
await completer.future;
await subscription.cancel();
}
Expand Down Expand Up @@ -429,6 +431,8 @@ class HotRunner extends ResidentRunner {

@override
Future<Null> cleanupAtFinish() async {
if (_isolateTracker != null)
await _isolateTracker.stop();
await _cleanupDevFS();
await stopEchoingDeviceLog();
}
Expand Down
68 changes: 68 additions & 0 deletions packages/flutter_tools/lib/src/isolate_tracker.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';

import 'globals.dart';
import 'observatory.dart';

// Track and report isolate life cycle events.
class IsolateTracker {
IsolateTracker(this.serviceProtocol);

// TODO(johnmccutchan): There can be more than one view.
String _viewIsolateId;
set viewIsolateId(String viewIsolateId) {
_viewIsolateId = viewIsolateId;
printStatus('View is now controlled by isolate $_viewIsolateId');
Copy link
Member

Choose a reason for hiding this comment

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

printTrace?

}
final Observatory serviceProtocol;
StreamSubscription<Event> _isolateEventSubscription;
StreamSubscription<Event> _debugEventSubscription;

bool _isViewIsolate(String isolateId) {
return (_viewIsolateId != null) && (_viewIsolateId == isolateId);
}

void onEvent(Event event) {
_onEvent(event);
}

Future<Null> _onEvent(Event event) async {
const List<String> kInterestingEventKinds =
const <String>['IsolateStart',
'IsolateExit',
'IsolateRunnable',
'PauseStart',
'PauseExit',
'PauseBreakpoint',
'PauseException'];
if (!kInterestingEventKinds.contains(event.kind))
return;
String messagePrefix = 'Isolate ${event.isolate.id}:';
if (_isViewIsolate(event.isolate.id)) {
messagePrefix = 'View isolate ${event.isolate.id}:';
}
if (event.kind == 'PauseExit') {
// TODO(johnmccutchan): Load the isolate and get any error.
}
printStatus('$messagePrefix ${event.kind}');
Copy link
Member

Choose a reason for hiding this comment

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

Probably printTrace here - status should be for user facing messages.

}

Future<Null> start() async {
Copy link
Member

Choose a reason for hiding this comment

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

Does this need to be async or return a Future?

if (_isolateEventSubscription != null) {
assert(_debugEventSubscription != null);
return;
}
_isolateEventSubscription =
serviceProtocol.onIsolateEvent.listen(onEvent);
_debugEventSubscription =
serviceProtocol.onDebugEvent.listen(onEvent);
}

Future<Null> stop() async {
_isolateEventSubscription?.cancel();
Copy link
Member

Choose a reason for hiding this comment

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

we should await these

_debugEventSubscription?.cancel();
}
}
25 changes: 13 additions & 12 deletions packages/flutter_tools/lib/src/observatory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class Observatory {
Stream<Event> get onEvent('Extension');
// IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate, ServiceExtensionAdded
Stream<Event> get onEvent('Isolate');
Stream<Event> get onEvent('Debug');
Stream<Event> get onEvent('Timeline');

// Listen for a specific event name.
Expand Down Expand Up @@ -134,18 +135,18 @@ class Observatory {
return views[0]['id'];
}

Future<Null> runInView(String viewId,
String main,
String packages,
String assetsDirectory) async {
await peer.sendRequest('_flutter.runInView',
<String, dynamic> {
'viewId': viewId,
'mainScript': main,
'packagesFile': packages,
'assetDirectory': assetsDirectory
});
return null;
Future<Response> runInView(String viewId,
String main,
String packages,
String assetsDirectory) async {
dynamic result = await peer.sendRequest('_flutter.runInView',
<String, dynamic> {
'viewId': viewId,
'mainScript': main,
'packagesFile': packages,
'assetDirectory': assetsDirectory
});
return new Response(result);
}

Future<Response> clearVMTimeline() => sendRequest('_clearVMTimeline');
Expand Down