OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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:convert'; |
7 import 'dart:io'; | 7 import 'dart:io'; |
8 import 'package:analysis_server/src/channel.dart'; | 8 import 'package:analysis_server/src/channel.dart'; |
9 import 'package:analysis_server/src/domain_server.dart'; | 9 import 'package:analysis_server/src/domain_server.dart'; |
10 import 'package:analysis_server/src/protocol.dart'; | 10 import 'package:analysis_server/src/protocol.dart'; |
11 | 11 |
12 /** | 12 /** |
13 * [AnalysisManager] is used to launch and manage an analysis server | 13 * [AnalysisManager] is used to launch and manage an analysis server |
14 * running in a separate process using either the [start] or [connect] methods. | 14 * running in a separate process using either the [start] or [connect] methods. |
15 */ | 15 */ |
16 class AnalysisManager { | 16 class AnalysisManager { |
17 // TODO dynamically allocate port and/or allow client to specify port | 17 // TODO dynamically allocate port and/or allow client to specify port |
18 static const int PORT = 3333; | 18 static const int PORT = 3333; |
19 | 19 |
20 /** | 20 /** |
21 * The analysis server process being managed | 21 * The analysis server process being managed |
22 * or `null` if managing an analysis server that was already running. | 22 * or `null` if managing an analysis server that was already running. |
23 */ | 23 */ |
24 Process process; | 24 Process process; |
25 | 25 |
26 /** | 26 /** |
27 * The socket used to communicate with the analysis server. | 27 * The channel used to communicate with the analysis server. |
28 */ | 28 */ |
29 WebSocket socket; | 29 CommunicationChannel channel; |
30 | 30 |
31 /** | 31 /** |
32 * Launch analysis server in a separate process | 32 * Launch analysis server in a separate process |
33 * and return a future with a manager for that analysis server. | 33 * and return a future with a manager for that analysis server. |
34 */ | 34 */ |
35 static Future<AnalysisManager> start(String serverPath) { | 35 static Future<AnalysisManager> start(String serverPath) { |
36 return new AnalysisManager()._launchServer(serverPath); | 36 return new AnalysisManager()._launchServer(serverPath); |
37 } | 37 } |
38 | 38 |
39 /** | 39 /** |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
93 exitCode = 1; | 93 exitCode = 1; |
94 if (process != null) { | 94 if (process != null) { |
95 process.kill(); | 95 process.kill(); |
96 } | 96 } |
97 throw 'Failed to connect to analysis server at $serverUrl\n $error'; | 97 throw 'Failed to connect to analysis server at $serverUrl\n $error'; |
98 }; | 98 }; |
99 try { | 99 try { |
100 return WebSocket.connect(serverUrl) | 100 return WebSocket.connect(serverUrl) |
101 .catchError(onError) | 101 .catchError(onError) |
102 .then((WebSocket socket) { | 102 .then((WebSocket socket) { |
103 this.socket = socket; | 103 this.channel = new WebSocketChannel(socket); |
104 return this; | 104 return this; |
105 }); | 105 }); |
106 } catch (error) { | 106 } catch (error) { |
107 onError(error); | 107 onError(error); |
108 } | 108 } |
109 } | 109 } |
110 | 110 |
111 /** | 111 /** |
112 * Stop the analysis server. | 112 * Stop the analysis server. |
113 * | 113 * |
114 * Returns `true` if the signal is successfully sent and process terminates. | 114 * Returns `true` if the signal is successfully sent and process terminates. |
115 * Otherwise there was no attached process or the signal could not be sent, | 115 * Otherwise there was no attached process or the signal could not be sent, |
116 * usually meaning that the process is already dead. | 116 * usually meaning that the process is already dead. |
117 */ | 117 */ |
118 Future<bool> stop() { | 118 Future<bool> stop() { |
119 if (process == null) { | 119 if (process == null) { |
120 return new Future.value(false); | 120 return new Future.value(false); |
121 } | 121 } |
122 var shutdownRequest = { | 122 var request = new Request('0', ServerDomainHandler.SHUTDOWN_METHOD); |
123 Request.ID : '0', | 123 channel.sendRequest(request); |
124 Request.METHOD : ServerDomainHandler.SHUTDOWN_METHOD }; | |
125 socket.add(JSON.encoder.convert(shutdownRequest)); | |
126 return process.exitCode | 124 return process.exitCode |
127 .timeout(new Duration(seconds: 10)) | 125 .timeout(new Duration(seconds: 10)) |
128 .catchError((error) { | 126 .catchError((error) { |
129 process.kill(); | 127 process.kill(); |
130 throw 'Expected server to shutdown'; | 128 throw 'Expected server to shutdown'; |
131 }) | 129 }) |
132 .then((result) { | 130 .then((result) { |
133 if (result != 0) { | 131 if (result != 0) { |
134 exitCode = result; | 132 exitCode = result; |
135 } | 133 } |
136 return true; | 134 return true; |
137 }); | 135 }); |
138 } | 136 } |
139 | 137 |
140 } | 138 } |
OLD | NEW |