Chromium Code Reviews| Index: pkg/analysis_server/lib/src/analysis_manager.dart |
| diff --git a/pkg/analysis_server/lib/src/analysis_manager.dart b/pkg/analysis_server/lib/src/analysis_manager.dart |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..44bd0a1e7211e8240aacb5122653d956bc696a5e |
| --- /dev/null |
| +++ b/pkg/analysis_server/lib/src/analysis_manager.dart |
| @@ -0,0 +1,75 @@ |
| +// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| +// for details. All rights reserved. Use of this source code is governed by a |
| +// BSD-style license that can be found in the LICENSE file. |
| + |
| +import 'dart:async'; |
| +import 'dart:convert'; |
| +import 'dart:io'; |
| + |
| +/** |
| + * [AnalysisManager] is used to launch and manage an analysis server |
| + * running in a separate process using the static [start] method. |
| + */ |
| +class AnalysisManager { |
| + // TODO dynamically allocate port and/or allow client to specify port |
| + static const int PORT = 3333; |
| + |
| + /** |
| + * The analysis server process being managed. |
| + */ |
| + final Process process; |
| + |
| + /** |
| + * The websocket used to communicate with the analysis server. |
| + */ |
| + final WebSocket socket; |
| + |
| + /** |
| + * Launch analysis server in a separate process and return a |
| + * [Future<AnalysisManager>] for managing that analysis server. |
| + */ |
| + static Future<AnalysisManager> start(String pathToServer) { |
| + // TODO dynamically allocate port and/or allow client to specify port |
| + return Process.start(Platform.executable, [pathToServer, "--port", |
| + PORT.toString()]).then(_connect); |
| + } |
| + |
| + /** |
| + * Open a connection to the analysis server. |
| + */ |
| + static Future<AnalysisManager> _connect(Process process) { |
| + var url = 'ws://${InternetAddress.LOOPBACK_IP_V4.address}:$PORT/'; |
| + process.stderr.pipe(stderr); |
| + Stream out = process.stdout.transform(UTF8.decoder).asBroadcastStream(); |
| + out.listen((line) { |
| + print(line); |
| + }); |
| + return out |
| + .any((String line) => line.startsWith("Listening on port")) |
| + .then((bool listening) { |
| + if (!listening) { |
| + throw "Expected analysis server to listen on a port"; |
| + } |
| + }) |
| + .then((_) => WebSocket.connect(url)) |
| + .then((WebSocket socket) => new AnalysisManager(process, socket)) |
| + .catchError((error) { |
| + process.kill(); |
| + throw error; |
| + }); |
| + } |
| + |
| + /** |
| + * Create a new instance that manages the specified analysis server process. |
| + */ |
| + AnalysisManager(this.process, this.socket); |
| + |
| + /** |
| + * Stop the analysis server. |
| + * |
| + * Returns [:true:] if the signal is successfully sent and process is killed. |
| + * Otherwise the signal could not be sent, usually meaning that the process |
| + * is already dead. |
| + */ |
| + bool stop() => process.kill(); |
|
Brian Wilkerson
2014/02/21 15:09:54
It would be nicer to ask the server to quit than t
|
| +} |