blob: 3d012056a9bec0f6323ef9542e5f07fde1b926b1 [file] [log] [blame]
// Copyright (c) 2017, 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 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/plugin/plugin_manager.dart';
import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;
mixin RequestHandlerMixin<T extends AnalysisServer> {
/// The analysis server that is using this handler to process requests.
T get server;
/// Given a mapping from plugins to futures that will complete when the plugin
/// has responded to a request, wait for a finite amount of time for each of
/// the plugins to respond. Return a list of the responses from each of the
/// plugins. If a plugin fails to return a response, notify the plugin manager
/// associated with the server so that non-responsive plugins can be killed or
/// restarted. The [timeout] is the maximum amount of time that will be spent
/// waiting for plugins to respond.
Future<List<plugin.Response>> waitForResponses(
Map<PluginInfo, Future<plugin.Response>> futures, {
plugin.RequestParams? requestParameters,
Duration timeout = const Duration(milliseconds: 500),
}) async {
// TODO(brianwilkerson): requestParameters might need to be required.
var timer = Stopwatch()..start();
var responses = <plugin.Response>[];
for (var entry in futures.entries) {
var pluginInfo = entry.key;
var future = entry.value;
try {
var response = await future.timeout(timeout - timer.elapsed);
var error = response.error;
if (error != null) {
// TODO(brianwilkerson): Report the error to the plugin manager.
server.instrumentationService.logPluginError(
pluginInfo.data,
error.code.name,
error.message,
error.stackTrace ?? StackTrace.current.toString(),
);
} else {
responses.add(response);
}
} on TimeoutException {
// TODO(brianwilkerson): Report the timeout to the plugin manager.
server.instrumentationService.logPluginTimeout(
pluginInfo.data,
JsonEncoder().convert(
requestParameters?.toRequest('-').toJson() ?? {},
),
);
} catch (exception, stackTrace) {
// TODO(brianwilkerson): Report the exception to the plugin manager.
server.instrumentationService.logPluginException(
pluginInfo.data,
exception,
stackTrace,
);
}
}
return responses;
}
}