| 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 |