From ad5da2976b4af8904305dc949df561ea938cf75a Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Mon, 15 Nov 2021 16:48:42 +0000 Subject: [PATCH] Add optional 'timeout' field to 'completion.getSuggestions2'. The intended use is in benchmarking, to specify a long timeout, so that the first time, when we warm up, we do necessary one time work, which would usually run out of budget the first few times. So, the requests that we do measure are more stable. Change-Id: I22e870b84dcd6f2ac201c5ec57081c39c6529ea1 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/220129 Commit-Queue: Konstantin Shcheglov Reviewed-by: Brian Wilkerson --- .../lib/protocol/protocol_constants.dart | 1 + .../lib/protocol/protocol_generated.dart | 24 ++++++++++++++++--- .../lib/src/domain_completion.dart | 9 +++++-- .../support/integration_test_methods.dart | 8 ++++--- .../support/protocol_matchers.dart | 3 ++- .../spec/generated/java/AnalysisServer.java | 6 ++++- pkg/analysis_server/tool/spec/spec_input.html | 10 ++++++++ .../lib/src/protocol/protocol_constants.dart | 1 + .../lib/src/protocol/protocol_generated.dart | 24 ++++++++++++++++--- 9 files changed, 73 insertions(+), 13 deletions(-) diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart index 2689506f371..85a4474eac5 100644 --- a/pkg/analysis_server/lib/protocol/protocol_constants.dart +++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart @@ -141,6 +141,7 @@ const String COMPLETION_REQUEST_GET_SUGGESTIONS2 = 'completion.getSuggestions2'; const String COMPLETION_REQUEST_GET_SUGGESTIONS2_FILE = 'file'; const String COMPLETION_REQUEST_GET_SUGGESTIONS2_MAX_RESULTS = 'maxResults'; const String COMPLETION_REQUEST_GET_SUGGESTIONS2_OFFSET = 'offset'; +const String COMPLETION_REQUEST_GET_SUGGESTIONS2_TIMEOUT = 'timeout'; const String COMPLETION_REQUEST_GET_SUGGESTIONS_FILE = 'file'; const String COMPLETION_REQUEST_GET_SUGGESTIONS_OFFSET = 'offset'; const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS = diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart index 8cd904d16f8..082036f72f7 100644 --- a/pkg/analysis_server/lib/protocol/protocol_generated.dart +++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart @@ -4698,7 +4698,14 @@ class CompletionGetSuggestions2Params implements RequestParams { /// to true. int maxResults; - CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults); + /// The approximate time in milliseconds that the server should spend. The + /// server will perform some steps anyway, even if it takes longer than the + /// specified timeout. This field is intended to be used for benchmarking, + /// and usually should not be provided, so that the default timeout is used. + int? timeout; + + CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults, + {this.timeout}); factory CompletionGetSuggestions2Params.fromJson( JsonDecoder jsonDecoder, String jsonPath, Object? json) { @@ -4723,7 +4730,12 @@ class CompletionGetSuggestions2Params implements RequestParams { } else { throw jsonDecoder.mismatch(jsonPath, 'maxResults'); } - return CompletionGetSuggestions2Params(file, offset, maxResults); + int? timeout; + if (json.containsKey('timeout')) { + timeout = jsonDecoder.decodeInt(jsonPath + '.timeout', json['timeout']); + } + return CompletionGetSuggestions2Params(file, offset, maxResults, + timeout: timeout); } else { throw jsonDecoder.mismatch( jsonPath, 'completion.getSuggestions2 params', json); @@ -4741,6 +4753,10 @@ class CompletionGetSuggestions2Params implements RequestParams { result['file'] = file; result['offset'] = offset; result['maxResults'] = maxResults; + var timeout = this.timeout; + if (timeout != null) { + result['timeout'] = timeout; + } return result; } @@ -4757,7 +4773,8 @@ class CompletionGetSuggestions2Params implements RequestParams { if (other is CompletionGetSuggestions2Params) { return file == other.file && offset == other.offset && - maxResults == other.maxResults; + maxResults == other.maxResults && + timeout == other.timeout; } return false; } @@ -4767,6 +4784,7 @@ class CompletionGetSuggestions2Params implements RequestParams { file, offset, maxResults, + timeout, ); } diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart index cfc49ebba7a..60c81b6a84b 100644 --- a/pkg/analysis_server/lib/src/domain_completion.dart +++ b/pkg/analysis_server/lib/src/domain_completion.dart @@ -267,12 +267,17 @@ class CompletionDomainHandler extends AbstractRequestHandler { /// Implement the 'completion.getSuggestions2' request. void getSuggestions2(Request request) async { - var budget = CompletionBudget(budgetDuration); - var params = CompletionGetSuggestions2Params.fromRequest(request); var file = params.file; var offset = params.offset; + var timeoutMilliseconds = params.timeout; + var budget = CompletionBudget( + timeoutMilliseconds != null + ? Duration(milliseconds: timeoutMilliseconds) + : budgetDuration, + ); + var provider = server.resourceProvider; var pathContext = provider.pathContext; diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart index 9a707cfd852..aa0d470a9a4 100644 --- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart +++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart @@ -1020,9 +1020,11 @@ abstract class IntegrationTestMixin { /// True if the number of suggestions after filtering was greater than the /// requested maxResults. Future sendCompletionGetSuggestions2( - String file, int offset, int maxResults) async { - var params = - CompletionGetSuggestions2Params(file, offset, maxResults).toJson(); + String file, int offset, int maxResults, + {int? timeout}) async { + var params = CompletionGetSuggestions2Params(file, offset, maxResults, + timeout: timeout) + .toJson(); var result = await server.send('completion.getSuggestions2', params); var decoder = ResponseDecoder(null); return CompletionGetSuggestions2Result.fromJson(decoder, 'result', result); diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart index 5fd8c3cfaf1..70848d4a6ba 100644 --- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart +++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart @@ -2139,7 +2139,8 @@ final Matcher isCompletionGetSuggestionDetailsResult = LazyMatcher(() => /// } final Matcher isCompletionGetSuggestions2Params = LazyMatcher(() => MatchesJsonObject('completion.getSuggestions2 params', - {'file': isFilePath, 'offset': isInt, 'maxResults': isInt})); + {'file': isFilePath, 'offset': isInt, 'maxResults': isInt}, + optionalFields: {'timeout': isInt})); /// completion.getSuggestions2 result /// diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java index 9f7e268f747..21085163fc0 100644 --- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java +++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java @@ -441,8 +441,12 @@ public interface AnalysisServer { * @param offset The offset within the file at which suggestions are to be made. * @param maxResults The maximum number of suggestions to return. If the number of suggestions * after filtering is greater than the maxResults, then isIncomplete is set to true. + * @param timeout The approximate time in milliseconds that the server should spend. The server + * will perform some steps anyway, even if it takes longer than the specified timeout. This + * field is intended to be used for benchmarking, and usually should not be provided, so + * that the default timeout is used. */ - public void completion_getSuggestions2(String file, int offset, int maxResults, GetSuggestions2Consumer consumer); + public void completion_getSuggestions2(String file, int offset, int maxResults, int timeout, GetSuggestions2Consumer consumer); /** * {@code completion.registerLibraryPaths} diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html index aa08d7450a5..d89a44b8f07 100644 --- a/pkg/analysis_server/tool/spec/spec_input.html +++ b/pkg/analysis_server/tool/spec/spec_input.html @@ -1482,6 +1482,16 @@ then isIncomplete is set to true.

+ + int +

+ The approximate time in milliseconds that the server should spend. + The server will perform some steps anyway, even if it takes longer + than the specified timeout. This field is intended to be used for + benchmarking, and usually should not be provided, so that the + default timeout is used. +

+
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart index 2689506f371..85a4474eac5 100644 --- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart +++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart @@ -141,6 +141,7 @@ const String COMPLETION_REQUEST_GET_SUGGESTIONS2 = 'completion.getSuggestions2'; const String COMPLETION_REQUEST_GET_SUGGESTIONS2_FILE = 'file'; const String COMPLETION_REQUEST_GET_SUGGESTIONS2_MAX_RESULTS = 'maxResults'; const String COMPLETION_REQUEST_GET_SUGGESTIONS2_OFFSET = 'offset'; +const String COMPLETION_REQUEST_GET_SUGGESTIONS2_TIMEOUT = 'timeout'; const String COMPLETION_REQUEST_GET_SUGGESTIONS_FILE = 'file'; const String COMPLETION_REQUEST_GET_SUGGESTIONS_OFFSET = 'offset'; const String COMPLETION_REQUEST_GET_SUGGESTION_DETAILS = diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart index 2dcbd32b065..2ebd67f4bb3 100644 --- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart +++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart @@ -4698,7 +4698,14 @@ class CompletionGetSuggestions2Params implements RequestParams { /// to true. int maxResults; - CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults); + /// The approximate time in milliseconds that the server should spend. The + /// server will perform some steps anyway, even if it takes longer than the + /// specified timeout. This field is intended to be used for benchmarking, + /// and usually should not be provided, so that the default timeout is used. + int? timeout; + + CompletionGetSuggestions2Params(this.file, this.offset, this.maxResults, + {this.timeout}); factory CompletionGetSuggestions2Params.fromJson( JsonDecoder jsonDecoder, String jsonPath, Object? json) { @@ -4723,7 +4730,12 @@ class CompletionGetSuggestions2Params implements RequestParams { } else { throw jsonDecoder.mismatch(jsonPath, 'maxResults'); } - return CompletionGetSuggestions2Params(file, offset, maxResults); + int? timeout; + if (json.containsKey('timeout')) { + timeout = jsonDecoder.decodeInt(jsonPath + '.timeout', json['timeout']); + } + return CompletionGetSuggestions2Params(file, offset, maxResults, + timeout: timeout); } else { throw jsonDecoder.mismatch( jsonPath, 'completion.getSuggestions2 params', json); @@ -4741,6 +4753,10 @@ class CompletionGetSuggestions2Params implements RequestParams { result['file'] = file; result['offset'] = offset; result['maxResults'] = maxResults; + var timeout = this.timeout; + if (timeout != null) { + result['timeout'] = timeout; + } return result; } @@ -4757,7 +4773,8 @@ class CompletionGetSuggestions2Params implements RequestParams { if (other is CompletionGetSuggestions2Params) { return file == other.file && offset == other.offset && - maxResults == other.maxResults; + maxResults == other.maxResults && + timeout == other.timeout; } return false; } @@ -4767,6 +4784,7 @@ class CompletionGetSuggestions2Params implements RequestParams { file, offset, maxResults, + timeout, ); }