Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(350)

Unified Diff: pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart

Issue 2676633003: Add server-side communications channel (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
diff --git a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
index a7ccafc82ea823b79288bdc92ce7d67ccff7953f..c3048d4201d639a4d1565cfd3bc1b8c02848f851 100644
--- a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
+++ b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
@@ -13,7 +13,7 @@ import 'package:analyzer_plugin/protocol/protocol.dart';
* both [Response]s and [Notification]s. It communicates with the analysis
* server by passing data to the server's main isolate.
*/
-class IsolateChannel implements PluginCommunicationChannel {
+class PluginIsolateChannel implements PluginCommunicationChannel {
/**
* The port used to send notifications and responses to the server.
*/
@@ -32,7 +32,7 @@ class IsolateChannel implements PluginCommunicationChannel {
/**
* Initialize a newly created channel to communicate with the server.
*/
- IsolateChannel(this._sendPort) {
+ PluginIsolateChannel(this._sendPort) {
_receivePort = new ReceivePort();
_sendPort.send(_receivePort.sendPort);
}
@@ -73,3 +73,83 @@ class IsolateChannel implements PluginCommunicationChannel {
_sendPort.send(response.toJson());
}
}
+
+/**
+ * The communication channel that allows an analysis server to send [Request]s
+ * to, and to receive both [Response]s and [Notification]s from, a plugin.
+ */
+class ServerIsolateChannel implements ServerCommunicationChannel {
+ /**
+ * The URI for the plugin that will be run in the isolate that this channel
+ * communicates with.
+ */
+ final Uri uri;
+
+ /**
+ * The isolate in which the plugin is running, or `null` if the plugin has
+ * not yet been started by invoking [listen].
+ */
+ Isolate _isolate;
+
+ /**
+ * The port used to send requests to the plugin, or `null` if the plugin has
+ * not yet been started by invoking [listen].
+ */
+ SendPort _sendPort;
+
+ /**
+ * Initialize a newly created channel to communicate with an isolate running
+ * the code at the given [uri].
+ */
+ ServerIsolateChannel(this.uri);
+
+ @override
+ void close() {
+ // TODO(brianwilkerson) Is there anything useful to do here?
+ _isolate = null;
+ _sendPort = null;
+ }
+
+ @override
+ Future<Null> listen(void onResponse(Response response),
+ void onNotification(Notification notification),
+ {Function onError, void onDone()}) async {
+ if (_isolate != null) {
+ throw new StateError('Cannot listen to the same channel more than once.');
+ }
+ ReceivePort receivePort = new ReceivePort();
+ ReceivePort errorPort;
+ if (onError != null) {
+ errorPort = new ReceivePort();
+ errorPort.listen((error) {
+ onError(error);
+ });
+ }
+ ReceivePort exitPort;
+ if (onDone != null) {
+ exitPort = new ReceivePort();
+ exitPort.listen((_) {
+ onDone();
+ });
+ }
+ _isolate = await Isolate.spawnUri(uri, <String>[], receivePort.sendPort,
+ automaticPackageResolution: true,
+ onError: errorPort?.sendPort,
+ onExit: exitPort?.sendPort);
+ _sendPort = await receivePort.first as SendPort;
+ receivePort.listen((dynamic input) {
+ if (input is Map) {
+ if (input.containsKey('id') != null) {
+ onResponse(new Response.fromJson(input));
+ } else if (input.containsKey('event')) {
+ onNotification(new Notification.fromJson(input));
+ }
+ }
+ });
+ }
+
+ @override
+ void sendRequest(Request request) {
+ _sendPort.send(request.toJson());
+ }
+}

Powered by Google App Engine
This is Rietveld 408576698