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

Side by Side Diff: pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart

Issue 2748683003: Fix bugs and add instrumentation (Closed)
Patch Set: Created 3 years, 9 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 unified diff | Download patch
« no previous file with comments | « pkg/analyzer_plugin/lib/protocol/protocol.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:convert';
6 import 'dart:isolate'; 7 import 'dart:isolate';
7 8
9 import 'package:analyzer/instrumentation/instrumentation.dart';
8 import 'package:analyzer_plugin/channel/channel.dart'; 10 import 'package:analyzer_plugin/channel/channel.dart';
9 import 'package:analyzer_plugin/protocol/protocol.dart'; 11 import 'package:analyzer_plugin/protocol/protocol.dart';
10 12
11 /** 13 /**
12 * The object that allows a [ServerPlugin] to receive [Request]s and to return 14 * The object that allows a [ServerPlugin] to receive [Request]s and to return
13 * both [Response]s and [Notification]s. It communicates with the analysis 15 * both [Response]s and [Notification]s. It communicates with the analysis
14 * server by passing data to the server's main isolate. 16 * server by passing data to the server's main isolate.
15 */ 17 */
16 class PluginIsolateChannel implements PluginCommunicationChannel { 18 class PluginIsolateChannel implements PluginCommunicationChannel {
17 /** 19 /**
(...skipping 25 matching lines...) Expand all
43 _subscription.cancel(); 45 _subscription.cancel();
44 _subscription = null; 46 _subscription = null;
45 } 47 }
46 } 48 }
47 49
48 @override 50 @override
49 void listen(void onRequest(Request request), 51 void listen(void onRequest(Request request),
50 {Function onError, void onDone()}) { 52 {Function onError, void onDone()}) {
51 void onData(data) { 53 void onData(data) {
52 Map<String, Object> requestMap = data; 54 Map<String, Object> requestMap = data;
55 // print('[plugin] Received request: ${JSON.encode(requestMap)}');
53 Request request = new Request.fromJson(requestMap); 56 Request request = new Request.fromJson(requestMap);
54 if (request != null) { 57 if (request != null) {
55 onRequest(request); 58 onRequest(request);
56 } 59 }
57 } 60 }
58 61
59 if (_subscription != null) { 62 if (_subscription != null) {
60 throw new StateError('Only one listener is allowed per channel'); 63 throw new StateError('Only one listener is allowed per channel');
61 } 64 }
62 _subscription = _receivePort.listen(onData, 65 _subscription = _receivePort.listen(onData,
63 onError: onError, onDone: onDone, cancelOnError: false); 66 onError: onError, onDone: onDone, cancelOnError: false);
64 } 67 }
65 68
66 @override 69 @override
67 void sendNotification(Notification notification) { 70 void sendNotification(Notification notification) {
68 _sendPort.send(notification.toJson()); 71 Map<String, Object> json = notification.toJson();
72 // print('[plugin] Send notification: ${JSON.encode(json)}');
73 _sendPort.send(json);
69 } 74 }
70 75
71 @override 76 @override
72 void sendResponse(Response response) { 77 void sendResponse(Response response) {
73 _sendPort.send(response.toJson()); 78 Map<String, Object> json = response.toJson();
79 // print('[plugin] Send response: ${JSON.encode(json)}');
80 _sendPort.send(json);
74 } 81 }
75 } 82 }
76 83
77 /** 84 /**
78 * The communication channel that allows an analysis server to send [Request]s 85 * The communication channel that allows an analysis server to send [Request]s
79 * to, and to receive both [Response]s and [Notification]s from, a plugin. 86 * to, and to receive both [Response]s and [Notification]s from, a plugin.
80 */ 87 */
81 class ServerIsolateChannel implements ServerCommunicationChannel { 88 class ServerIsolateChannel implements ServerCommunicationChannel {
82 /** 89 /**
83 * The URI for the plugin that will be run in the isolate that this channel 90 * The URI for the Dart file that will be run in the isolate that this channel
84 * communicates with. 91 * communicates with.
85 */ 92 */
86 final Uri uri; 93 final Uri pluginUri;
94
95 /**
96 * The URI for the '.packages' file that will control how 'package:' URIs are
97 * resolved.
98 */
99 final Uri packagesUri;
100
101 /**
102 * The instrumentation service that is being used by the analysis server.
103 */
104 final InstrumentationService instrumentationService;
87 105
88 /** 106 /**
89 * The isolate in which the plugin is running, or `null` if the plugin has 107 * The isolate in which the plugin is running, or `null` if the plugin has
90 * not yet been started by invoking [listen]. 108 * not yet been started by invoking [listen].
91 */ 109 */
92 Isolate _isolate; 110 Isolate _isolate;
93 111
94 /** 112 /**
95 * The port used to send requests to the plugin, or `null` if the plugin has 113 * The port used to send requests to the plugin, or `null` if the plugin has
96 * not yet been started by invoking [listen]. 114 * not yet been started by invoking [listen].
97 */ 115 */
98 SendPort _sendPort; 116 SendPort _sendPort;
99 117
118 ReceivePort receivePort;
119
120 ReceivePort errorPort;
121
122 ReceivePort exitPort;
123
100 /** 124 /**
101 * Initialize a newly created channel to communicate with an isolate running 125 * Initialize a newly created channel to communicate with an isolate running
102 * the code at the given [uri]. 126 * the code at the given [uri].
103 */ 127 */
104 ServerIsolateChannel(this.uri); 128 ServerIsolateChannel(
105 129 this.pluginUri, this.packagesUri, this.instrumentationService);
106 @override 130 @override
107 void close() { 131 void close() {
108 // TODO(brianwilkerson) Is there anything useful to do here? 132 receivePort?.close();
133 errorPort?.close();
134 exitPort?.close();
109 _isolate = null; 135 _isolate = null;
110 _sendPort = null; 136 // _sendPort = null;
137 // receivePort = null;
138 // errorPort = null;
139 // exitPort = null;
111 } 140 }
112 141
113 @override 142 @override
114 Future<Null> listen(void onResponse(Response response), 143 Future<Null> listen(void onResponse(Response response),
115 void onNotification(Notification notification), 144 void onNotification(Notification notification),
116 {Function onError, void onDone()}) async { 145 {Function onError, void onDone()}) async {
117 if (_isolate != null) { 146 if (_isolate != null) {
118 throw new StateError('Cannot listen to the same channel more than once.'); 147 throw new StateError('Cannot listen to the same channel more than once.');
119 } 148 }
120 ReceivePort receivePort = new ReceivePort(); 149 receivePort = new ReceivePort();
121 ReceivePort errorPort;
122 if (onError != null) { 150 if (onError != null) {
123 errorPort = new ReceivePort(); 151 errorPort = new ReceivePort();
124 errorPort.listen((error) { 152 errorPort.listen((error) {
125 onError(error); 153 onError(error);
126 }); 154 });
127 } 155 }
128 ReceivePort exitPort;
129 if (onDone != null) { 156 if (onDone != null) {
130 exitPort = new ReceivePort(); 157 exitPort = new ReceivePort();
131 exitPort.listen((_) { 158 exitPort.listen((_) {
132 onDone(); 159 onDone();
133 }); 160 });
134 } 161 }
135 _isolate = await Isolate.spawnUri(uri, <String>[], receivePort.sendPort, 162 _isolate = await Isolate.spawnUri(
136 automaticPackageResolution: true, 163 pluginUri, <String>[], receivePort.sendPort,
137 onError: errorPort?.sendPort, 164 onError: errorPort?.sendPort,
138 onExit: exitPort?.sendPort); 165 onExit: exitPort?.sendPort,
139 _sendPort = await receivePort.first as SendPort; 166 packageConfig: packagesUri);
167 Completer<Null> channelReady = new Completer<Null>();
140 receivePort.listen((dynamic input) { 168 receivePort.listen((dynamic input) {
141 if (input is Map) { 169 if (input is SendPort) {
170 // print('[server] Received send port');
171 _sendPort = input;
172 channelReady.complete(null);
173 } else if (input is Map) {
142 if (input.containsKey('id') != null) { 174 if (input.containsKey('id') != null) {
175 String encodedInput = JSON.encode(input);
176 // print('[server] Received response: $encodedInput');
177 instrumentationService.logPluginResponse(pluginUri, encodedInput);
143 onResponse(new Response.fromJson(input)); 178 onResponse(new Response.fromJson(input));
144 } else if (input.containsKey('event')) { 179 } else if (input.containsKey('event')) {
180 String encodedInput = JSON.encode(input);
181 // print('[server] Received notification: $encodedInput');
182 instrumentationService.logPluginNotification(pluginUri, encodedInput);
145 onNotification(new Notification.fromJson(input)); 183 onNotification(new Notification.fromJson(input));
146 } 184 }
147 } 185 }
148 }); 186 });
187 return channelReady.future;
149 } 188 }
150 189
151 @override 190 @override
152 void sendRequest(Request request) { 191 void sendRequest(Request request) {
153 _sendPort.send(request.toJson()); 192 Map<String, Object> json = request.toJson();
193 String encodedRequest = JSON.encode(json);
194 // print('[server] Send request: $encodedRequest');
195 instrumentationService.logPluginRequest(pluginUri, encodedRequest);
196 _sendPort.send(json);
154 } 197 }
155 } 198 }
OLDNEW
« no previous file with comments | « pkg/analyzer_plugin/lib/protocol/protocol.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698