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 | 8 |
9 import 'package:analysis_server/src/channel/channel.dart'; | 9 import 'package:analysis_server/src/channel/channel.dart'; |
10 import 'package:analysis_server/src/channel/web_socket_channel.dart'; | 10 import 'package:analysis_server/src/channel/web_socket_channel.dart'; |
(...skipping 22 matching lines...) Expand all Loading... |
33 * Stop the analysis server. | 33 * Stop the analysis server. |
34 * | 34 * |
35 * Returns `true` if the signal is successfully sent and process terminates. | 35 * Returns `true` if the signal is successfully sent and process terminates. |
36 * Otherwise there was no attached process or the signal could not be sent, | 36 * Otherwise there was no attached process or the signal could not be sent, |
37 * usually meaning that the process is already dead. | 37 * usually meaning that the process is already dead. |
38 */ | 38 */ |
39 Future<bool> stop() { | 39 Future<bool> stop() { |
40 if (process == null) { | 40 if (process == null) { |
41 return channel.close().then((_) => false); | 41 return channel.close().then((_) => false); |
42 } | 42 } |
43 return channel.sendRequest( | 43 return channel |
44 new ServerShutdownParams().toRequest( | 44 .sendRequest(new ServerShutdownParams().toRequest('0')) |
45 '0')).timeout(new Duration(seconds: 2), onTimeout: () { | 45 .timeout(new Duration(seconds: 2), onTimeout: () { |
46 print('Expected shutdown response'); | 46 print('Expected shutdown response'); |
47 }).then((Response response) { | 47 }).then((Response response) { |
48 return channel.close().then((_) => process.exitCode); | 48 return channel.close().then((_) => process.exitCode); |
49 }).timeout(new Duration(seconds: 2), onTimeout: () { | 49 }).timeout(new Duration(seconds: 2), onTimeout: () { |
50 print('Expected server to shutdown'); | 50 print('Expected server to shutdown'); |
51 process.kill(); | 51 process.kill(); |
52 }).then((int result) { | 52 }).then((int result) { |
53 if (result != null && result != 0) { | 53 if (result != null && result != 0) { |
54 exitCode = result; | 54 exitCode = result; |
55 } | 55 } |
(...skipping 19 matching lines...) Expand all Loading... |
75 Future<AnalysisManager> _listenForPort(Process process) { | 75 Future<AnalysisManager> _listenForPort(Process process) { |
76 this.process = process; | 76 this.process = process; |
77 | 77 |
78 // Echo stdout and stderr | 78 // Echo stdout and stderr |
79 Stream out = process.stdout.transform(UTF8.decoder).asBroadcastStream(); | 79 Stream out = process.stdout.transform(UTF8.decoder).asBroadcastStream(); |
80 out.listen((line) => print(line)); | 80 out.listen((line) => print(line)); |
81 process.stderr.pipe(stderr); | 81 process.stderr.pipe(stderr); |
82 | 82 |
83 // Listen for port from server | 83 // Listen for port from server |
84 const String pattern = 'Listening on port '; | 84 const String pattern = 'Listening on port '; |
85 return out.firstWhere( | 85 return out |
86 (String line) => | 86 .firstWhere((String line) => line.startsWith(pattern)) |
87 line.startsWith( | 87 .timeout(new Duration(seconds: 10)) |
88 pattern)).timeout(new Duration(seconds: 10)).catchError((error)
{ | 88 .catchError((error) { |
89 exitCode = 1; | 89 exitCode = 1; |
90 process.kill(); | 90 process.kill(); |
91 throw 'Expected port from analysis server'; | 91 throw 'Expected port from analysis server'; |
92 }).then((String line) { | 92 }).then((String line) { |
93 String port = line.substring(pattern.length).trim(); | 93 String port = line.substring(pattern.length).trim(); |
94 String url = 'ws://${InternetAddress.LOOPBACK_IP_V4.address}:$port/'; | 94 String url = 'ws://${InternetAddress.LOOPBACK_IP_V4.address}:$port/'; |
95 return _openConnection(url); | 95 return _openConnection(url); |
96 }); | 96 }); |
97 } | 97 } |
98 | 98 |
99 /** | 99 /** |
100 * Open a connection to the analysis server using the given URL. | 100 * Open a connection to the analysis server using the given URL. |
101 */ | 101 */ |
102 Future<AnalysisManager> _openConnection(String serverUrl) { | 102 Future<AnalysisManager> _openConnection(String serverUrl) { |
103 Function onError = (error) { | 103 Function onError = (error) { |
104 exitCode = 1; | 104 exitCode = 1; |
105 if (process != null) { | 105 if (process != null) { |
106 process.kill(); | 106 process.kill(); |
107 } | 107 } |
108 throw 'Failed to connect to analysis server at $serverUrl\n $error'; | 108 throw 'Failed to connect to analysis server at $serverUrl\n $error'; |
109 }; | 109 }; |
110 try { | 110 try { |
111 return WebSocket.connect( | 111 return WebSocket |
112 serverUrl).catchError(onError).then((WebSocket socket) { | 112 .connect(serverUrl) |
| 113 .catchError(onError) |
| 114 .then((WebSocket socket) { |
113 this.channel = new WebSocketClientChannel(socket); | 115 this.channel = new WebSocketClientChannel(socket); |
114 return this; | 116 return this; |
115 }); | 117 }); |
116 } catch (error) { | 118 } catch (error) { |
117 onError(error); | 119 onError(error); |
118 } | 120 } |
119 } | 121 } |
120 | 122 |
121 /** | 123 /** |
122 * Open a connection to a running analysis server | 124 * Open a connection to a running analysis server |
123 * and return a future with a manager for that analysis server. | 125 * and return a future with a manager for that analysis server. |
124 */ | 126 */ |
125 static Future<AnalysisManager> connect(String serverUrl) { | 127 static Future<AnalysisManager> connect(String serverUrl) { |
126 return new AnalysisManager()._openConnection(serverUrl); | 128 return new AnalysisManager()._openConnection(serverUrl); |
127 } | 129 } |
128 | 130 |
129 /** | 131 /** |
130 * Launch analysis server in a separate process | 132 * Launch analysis server in a separate process |
131 * and return a future with a manager for that analysis server. | 133 * and return a future with a manager for that analysis server. |
132 */ | 134 */ |
133 static Future<AnalysisManager> start(String serverPath) { | 135 static Future<AnalysisManager> start(String serverPath) { |
134 return new AnalysisManager()._launchServer(serverPath); | 136 return new AnalysisManager()._launchServer(serverPath); |
135 } | 137 } |
136 } | 138 } |
OLD | NEW |