Giving Analysis Servers it's own FlutterWebManager (#598)
diff --git a/benchmark/bench.dart b/benchmark/bench.dart
index ab6bd13..bf23ce1 100644
--- a/benchmark/bench.dart
+++ b/benchmark/bench.dart
@@ -13,18 +13,13 @@
import 'package:dart_services/src/bench.dart';
import 'package:dart_services/src/common.dart';
import 'package:dart_services/src/compiler.dart';
-import 'package:dart_services/src/flutter_web.dart';
void main(List<String> args) async {
final json = args.contains('--json');
final harness = BenchmarkHarness(asJson: json);
- final flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
- await flutterWebManager.warmup();
-
- final compiler =
- Compiler(SdkManager.sdk, SdkManager.flutterSdk, flutterWebManager);
+ final compiler = Compiler(SdkManager.sdk, SdkManager.flutterSdk);
Logger.root.level = Level.WARNING;
Logger.root.onRecord.listen((LogRecord record) {
diff --git a/lib/src/analysis_server.dart b/lib/src/analysis_server.dart
index 35ec013..3259650 100644
--- a/lib/src/analysis_server.dart
+++ b/lib/src/analysis_server.dart
@@ -15,6 +15,7 @@
import 'package:pedantic/pedantic.dart';
import 'common.dart';
+import 'common_server_impl.dart' show BadRequest;
import 'flutter_web.dart';
import 'protos/dart_services.pb.dart' as proto;
import 'pub.dart';
@@ -35,9 +36,9 @@
const Duration _ANALYSIS_SERVER_TIMEOUT = Duration(seconds: 35);
class AnalysisServersWrapper {
- AnalysisServersWrapper(this._flutterWebManager);
+ AnalysisServersWrapper();
- final FlutterWebManager _flutterWebManager;
+ FlutterWebManager _flutterWebManager;
DartAnalysisServerWrapper _dartAnalysisServer;
FlutterAnalysisServerWrapper _flutterAnalysisServer;
@@ -57,9 +58,10 @@
bool get isHealthy => (_restartingSince == null ||
DateTime.now().difference(_restartingSince).inMinutes < 30);
- Future<void> init() async {
+ Future<void> warmup() async {
_logger.info('Beginning AnalysisServersWrapper init().');
_dartAnalysisServer = DartAnalysisServerWrapper();
+ _flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
_flutterAnalysisServer = FlutterAnalysisServerWrapper(_flutterWebManager);
await _dartAnalysisServer.init();
@@ -83,19 +85,30 @@
}));
_restartingSince = null;
+
+ return Future.wait(<Future<dynamic>>[
+ _flutterWebManager.warmup(),
+ _flutterAnalysisServer.warmup(),
+ _dartAnalysisServer.warmup(),
+ ]);
}
- Future warmup() => Future.wait(<Future<dynamic>>[
- _flutterAnalysisServer.warmup(),
- _dartAnalysisServer.warmup(),
- ]);
+ Future<void> _restart() async {
+ _logger.warning('Restarting');
+ await shutdown();
+ _logger.info('shutdown');
+
+ await warmup();
+ _logger.warning('Restart complete');
+ }
Future<dynamic> shutdown() {
_restartingSince = DateTime.now();
return Future.wait(<Future<dynamic>>[
- _dartAnalysisServer.shutdown(),
+ _flutterWebManager.dispose(),
_flutterAnalysisServer.shutdown(),
+ _dartAnalysisServer.shutdown(),
]);
}
@@ -106,23 +119,71 @@
: _dartAnalysisServer;
}
- Future<proto.AnalysisResults> analyze(String source) =>
- _getCorrectAnalysisServer(source).analyze(source);
+ Future<proto.AnalysisResults> analyze(String source) => _perfLogAndRestart(
+ source,
+ () => _getCorrectAnalysisServer(source).analyze(source),
+ 'analysis',
+ 'Error during analyze on "$source"');
Future<proto.CompleteResponse> complete(String source, int offset) =>
- _getCorrectAnalysisServer(source).complete(source, offset);
+ _perfLogAndRestart(
+ source,
+ () => _getCorrectAnalysisServer(source).complete(source, offset),
+ 'completions',
+ 'Error during complete on "$source" at $offset');
Future<proto.FixesResponse> getFixes(String source, int offset) =>
- _getCorrectAnalysisServer(source).getFixes(source, offset);
+ _perfLogAndRestart(
+ source,
+ () => _getCorrectAnalysisServer(source).getFixes(source, offset),
+ 'fixes',
+ 'Error during fixes on "$source" at $offset');
Future<proto.AssistsResponse> getAssists(String source, int offset) =>
- _getCorrectAnalysisServer(source).getAssists(source, offset);
+ _perfLogAndRestart(
+ source,
+ () => _getCorrectAnalysisServer(source).getAssists(source, offset),
+ 'assists',
+ 'Error during assists on "$source" at $offset');
Future<proto.FormatResponse> format(String source, int offset) =>
- _getCorrectAnalysisServer(source).format(source, offset);
+ _perfLogAndRestart(
+ source,
+ () => _getCorrectAnalysisServer(source).format(source, offset),
+ 'format',
+ 'Error during format on "$source" at $offset');
Future<Map<String, String>> dartdoc(String source, int offset) =>
- _getCorrectAnalysisServer(source).dartdoc(source, offset);
+ _perfLogAndRestart(
+ source,
+ () => _getCorrectAnalysisServer(source).dartdoc(source, offset),
+ 'dartdoc',
+ 'Error during dartdoc on "$source" at $offset');
+
+ Future<T> _perfLogAndRestart<T>(String source, Future<T> Function() body,
+ String action, String errorDescription) async {
+ await _checkPackageReferences(source);
+ try {
+ final watch = Stopwatch()..start();
+ final response = await body();
+ _logger.info('PERF: Computed $action in ${watch.elapsedMilliseconds}ms.');
+ return response;
+ } catch (e, st) {
+ _logger.severe(errorDescription, e, st);
+ await _restart();
+ rethrow;
+ }
+ }
+
+ /// Check that the set of packages referenced is valid.
+ Future<void> _checkPackageReferences(String source) async {
+ final imports = getAllImportsFor(source);
+
+ if (_flutterWebManager.hasUnsupportedImport(imports)) {
+ throw BadRequest(
+ 'Unsupported input: ${_flutterWebManager.getUnsupportedImport(imports)}');
+ }
+ }
}
class DartAnalysisServerWrapper extends AnalysisServerWrapper {
diff --git a/lib/src/common_server_impl.dart b/lib/src/common_server_impl.dart
index 7c6c076..c383277 100644
--- a/lib/src/common_server_impl.dart
+++ b/lib/src/common_server_impl.dart
@@ -15,9 +15,7 @@
import 'analysis_server.dart';
import 'common.dart';
import 'compiler.dart';
-import 'flutter_web.dart';
import 'protos/dart_services.pb.dart' as proto;
-import 'pub.dart';
import 'sdk_manager.dart';
import 'server_cache.dart';
@@ -38,7 +36,6 @@
final ServerContainer container;
final ServerCache cache;
- FlutterWebManager flutterWebManager;
Compiler compiler;
AnalysisServersWrapper analysisServers;
@@ -57,33 +54,17 @@
Future<void> init() async {
log.info('Beginning CommonServer init().');
- flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
- analysisServers = AnalysisServersWrapper(flutterWebManager);
- compiler =
- Compiler(SdkManager.sdk, SdkManager.flutterSdk, flutterWebManager);
+ analysisServers = AnalysisServersWrapper();
+ compiler = Compiler(SdkManager.sdk, SdkManager.flutterSdk);
- await analysisServers.init();
- log.info('Analysis servers initialized.');
-
- await flutterWebManager.warmup();
await compiler.warmup();
await analysisServers.warmup();
}
- Future<void> restart() async {
- log.warning('Restarting CommonServer');
- await shutdown();
- log.info('Analysis Servers shutdown');
-
- await init();
- log.warning('Restart complete');
- }
-
Future<dynamic> shutdown() {
return Future.wait(<Future<dynamic>>[
analysisServers.shutdown(),
compiler.dispose(),
- flutterWebManager.dispose(),
Future<dynamic>.sync(cache.shutdown)
]).timeout(const Duration(minutes: 1));
}
@@ -93,11 +74,7 @@
throw BadRequest('Missing parameter: \'source\'');
}
- return _perfLogAndRestart(
- request.source,
- () => analysisServers.analyze(request.source),
- 'analysis',
- 'Error during analyze on "${request.source}"');
+ return analysisServers.analyze(request.source);
}
Future<proto.CompileResponse> compile(proto.CompileRequest request) {
@@ -125,11 +102,7 @@
throw BadRequest('Missing parameter: \'offset\'');
}
- return _perfLogAndRestart(
- request.source,
- () => analysisServers.complete(request.source, request.offset),
- 'completions',
- 'Error during complete on "${request.source}" at ${request.offset}');
+ return analysisServers.complete(request.source, request.offset);
}
Future<proto.FixesResponse> fixes(proto.SourceRequest request) {
@@ -140,11 +113,7 @@
throw BadRequest('Missing parameter: \'offset\'');
}
- return _perfLogAndRestart(
- request.source,
- () => analysisServers.getFixes(request.source, request.offset),
- 'fixes',
- 'Error during fixes on "${request.source}" at ${request.offset}');
+ return analysisServers.getFixes(request.source, request.offset);
}
Future<proto.AssistsResponse> assists(proto.SourceRequest request) {
@@ -155,11 +124,7 @@
throw BadRequest('Missing parameter: \'offset\'');
}
- return _perfLogAndRestart(
- request.source,
- () => analysisServers.getAssists(request.source, request.offset),
- 'assists',
- 'Error during assists on "${request.source}" at ${request.offset}');
+ return analysisServers.getAssists(request.source, request.offset);
}
Future<proto.FormatResponse> format(proto.SourceRequest request) {
@@ -167,14 +132,10 @@
throw BadRequest('Missing parameter: \'source\'');
}
- return _perfLogAndRestart(
- request.source,
- () => analysisServers.format(request.source, request.offset ?? 0),
- 'format',
- 'Error during format on "${request.source}" at ${request.offset}');
+ return analysisServers.format(request.source, request.offset ?? 0);
}
- Future<proto.DocumentResponse> document(proto.SourceRequest request) {
+ Future<proto.DocumentResponse> document(proto.SourceRequest request) async {
if (!request.hasSource()) {
throw BadRequest('Missing parameter: \'source\'');
}
@@ -182,14 +143,10 @@
throw BadRequest('Missing parameter: \'offset\'');
}
- return _perfLogAndRestart(
- request.source,
- () async => proto.DocumentResponse()
- ..info.addAll(
- await analysisServers.dartdoc(request.source, request.offset) ??
- <String, String>{}),
- 'dartdoc',
- 'Error during document on "${request.source}" at ${request.offset}');
+ return proto.DocumentResponse()
+ ..info.addAll(
+ await analysisServers.dartdoc(request.source, request.offset) ??
+ <String, String>{});
}
Future<proto.VersionResponse> version(proto.VersionRequest _) =>
@@ -210,8 +167,6 @@
bool returnSourceMap = false,
}) async {
try {
- await _checkPackageReferencesInitFlutterWeb(source);
-
final sourceHash = _hashSource(source);
final memCacheKey = '%%COMPILE:v0'
':returnSourceMap:$returnSourceMap:source:$sourceHash';
@@ -269,8 +224,6 @@
Future<proto.CompileDDCResponse> _compileDDC(String source) async {
try {
- await _checkPackageReferencesInitFlutterWeb(source);
-
final sourceHash = _hashSource(source);
final memCacheKey = '%%COMPILE_DDC:v0:source:$sourceHash';
@@ -321,34 +274,6 @@
Future<void> _setCache(String query, String result) =>
cache.set(query, result, expiration: _standardExpiration);
-
- /// Check that the set of packages referenced is valid.
- ///
- /// If there are uses of package:flutter, ensure that support there is
- /// initialized.
- Future<void> _checkPackageReferencesInitFlutterWeb(String source) async {
- final imports = getAllImportsFor(source);
-
- if (flutterWebManager.hasUnsupportedImport(imports)) {
- throw BadRequest(
- 'Unsupported input: ${flutterWebManager.getUnsupportedImport(imports)}');
- }
- }
-
- Future<T> _perfLogAndRestart<T>(String source, Future<T> Function() body,
- String action, String errorDescription) async {
- await _checkPackageReferencesInitFlutterWeb(source);
- try {
- final watch = Stopwatch()..start();
- final response = await body();
- log.info('PERF: Computed $action in ${watch.elapsedMilliseconds}ms.');
- return response;
- } catch (e, st) {
- log.severe(errorDescription, e, st);
- await restart();
- rethrow;
- }
- }
}
String _printCompileProblem(CompilationProblem problem) => problem.message;
diff --git a/lib/src/compiler.dart b/lib/src/compiler.dart
index 280bcb3..b45fd9a 100644
--- a/lib/src/compiler.dart
+++ b/lib/src/compiler.dart
@@ -28,20 +28,22 @@
final String _dartdevcPath;
final BazelWorkerDriver _ddcDriver;
- Compiler(this._sdk, this._flutterSdk, this._flutterWebManager)
+ Compiler(this._sdk, this._flutterSdk)
: _dartdevcPath = path.join(_flutterSdk.sdkPath, 'bin', 'dartdevc'),
_ddcDriver = BazelWorkerDriver(
() => Process.start(
path.join(_flutterSdk.sdkPath, 'bin', 'dartdevc'),
<String>['--persistent_worker'],
),
- maxWorkers: 1);
+ maxWorkers: 1),
+ _flutterWebManager = FlutterWebManager(_flutterSdk);
bool importsOkForCompile(Set<String> imports) {
return !_flutterWebManager.hasUnsupportedImport(imports);
}
- Future<CompilationResults> warmup({bool useHtml = false}) {
+ Future<CompilationResults> warmup({bool useHtml = false}) async {
+ await _flutterWebManager.warmup();
return compile(useHtml ? sampleCodeWeb : sampleCode);
}
@@ -186,7 +188,10 @@
}
}
- Future<void> dispose() => _ddcDriver.terminateWorkers();
+ Future<void> dispose() async {
+ await _flutterWebManager.dispose();
+ return _ddcDriver.terminateWorkers();
+ }
}
/// The result of a dart2js compile.
diff --git a/test/compiler_test.dart b/test/compiler_test.dart
index 2f39158..2f92115 100644
--- a/test/compiler_test.dart
+++ b/test/compiler_test.dart
@@ -6,7 +6,6 @@
import 'package:dart_services/src/common.dart';
import 'package:dart_services/src/compiler.dart';
-import 'package:dart_services/src/flutter_web.dart';
import 'package:dart_services/src/sdk_manager.dart';
import 'package:test/test.dart';
@@ -14,18 +13,14 @@
void defineTests() {
Compiler compiler;
- FlutterWebManager flutterWebManager;
group('compiler', () {
setUpAll(() async {
await SdkManager.sdk.init();
await SdkManager.flutterSdk.init();
- flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
- await flutterWebManager.warmup();
-
- compiler =
- Compiler(SdkManager.sdk, SdkManager.flutterSdk, flutterWebManager);
+ compiler = Compiler(SdkManager.sdk, SdkManager.flutterSdk);
+ await compiler.warmup();
});
tearDownAll(() async {
diff --git a/test/flutter_analysis_server_test.dart b/test/flutter_analysis_server_test.dart
index ece0438..92cfaee 100644
--- a/test/flutter_analysis_server_test.dart
+++ b/test/flutter_analysis_server_test.dart
@@ -233,21 +233,16 @@
group('Flutter SDK analysis_server with analysis servers', () {
AnalysisServersWrapper analysisServersWrapper;
- FlutterWebManager flutterWebManager;
setUp(() async {
await SdkManager.flutterSdk.init();
- flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
- await flutterWebManager.warmup();
- analysisServersWrapper = AnalysisServersWrapper(flutterWebManager);
- await analysisServersWrapper.init();
+ analysisServersWrapper = AnalysisServersWrapper();
await analysisServersWrapper.warmup();
});
tearDown(() async {
await analysisServersWrapper.shutdown();
- await flutterWebManager.dispose();
});
test('analyze counter app', () async {
diff --git a/tool/fuzz_driver.dart b/tool/fuzz_driver.dart
index 6059e17..7516dda 100644
--- a/tool/fuzz_driver.dart
+++ b/tool/fuzz_driver.dart
@@ -16,7 +16,6 @@
import 'package:dart_services/src/common.dart';
import 'package:dart_services/src/common_server_impl.dart';
import 'package:dart_services/src/compiler.dart' as comp;
-import 'package:dart_services/src/flutter_web.dart';
import 'package:dart_services/src/sdk_manager.dart';
import 'package:dart_services/src/server_cache.dart';
import 'package:dart_services/src/protos/dart_services.pb.dart' as proto;
@@ -122,8 +121,6 @@
print('SdKPath: $sdkPath');
- final flutterWebManager = FlutterWebManager(SdkManager.flutterSdk);
-
container = MockContainer();
cache = MockCache();
commonServerImpl = CommonServerImpl(container, cache);
@@ -136,8 +133,7 @@
await analysisServer.warmup();
print('Warming up compiler');
- compiler =
- comp.Compiler(SdkManager.sdk, SdkManager.flutterSdk, flutterWebManager);
+ compiler = comp.Compiler(SdkManager.sdk, SdkManager.flutterSdk);
await compiler.warmup();
print('SetupTools done');
}