Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(94)

Side by Side Diff: pkg/analysis_server/lib/src/domain_completion.dart

Issue 1539943002: stop caching state between completion requests (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: merge Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 library domain.completion; 5 library domain.completion;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analysis_server/plugin/protocol/protocol.dart'; 9 import 'package:analysis_server/plugin/protocol/protocol.dart';
10 import 'package:analysis_server/src/analysis_server.dart'; 10 import 'package:analysis_server/src/analysis_server.dart';
11 import 'package:analysis_server/src/constants.dart'; 11 import 'package:analysis_server/src/constants.dart';
12 import 'package:analysis_server/src/context_manager.dart';
13 import 'package:analysis_server/src/provisional/completion/completion_core.dart' 12 import 'package:analysis_server/src/provisional/completion/completion_core.dart'
14 show CompletionRequest, CompletionResult; 13 show CompletionRequest, CompletionResult;
15 import 'package:analysis_server/src/services/completion/completion_core.dart'; 14 import 'package:analysis_server/src/services/completion/completion_core.dart';
16 import 'package:analysis_server/src/services/completion/completion_manager.dart' ; 15 import 'package:analysis_server/src/services/completion/completion_manager.dart' ;
17 import 'package:analysis_server/src/services/search/search_engine.dart';
18 import 'package:analyzer/src/generated/engine.dart'; 16 import 'package:analyzer/src/generated/engine.dart';
19 import 'package:analyzer/src/generated/source.dart'; 17 import 'package:analyzer/src/generated/source.dart';
20 18
21 export 'package:analysis_server/src/services/completion/completion_manager.dart' 19 export 'package:analysis_server/src/services/completion/completion_manager.dart'
22 show CompletionPerformance, CompletionRequest, OperationPerformance; 20 show CompletionPerformance, CompletionRequest, OperationPerformance;
23 21
24 /** 22 /**
25 * Instances of the class [CompletionDomainHandler] implement a [RequestHandler] 23 * Instances of the class [CompletionDomainHandler] implement a [RequestHandler]
26 * that handles requests in the search domain. 24 * that handles requests in the search domain.
27 */ 25 */
28 class CompletionDomainHandler implements RequestHandler { 26 class CompletionDomainHandler implements RequestHandler {
29 /** 27 /**
30 * The maximum number of performance measurements to keep. 28 * The maximum number of performance measurements to keep.
31 */ 29 */
32 static const int performanceListMaxLength = 50; 30 static const int performanceListMaxLength = 50;
33 31
34 /** 32 /**
35 * The analysis server that is using this handler to process requests. 33 * The analysis server that is using this handler to process requests.
36 */ 34 */
37 final AnalysisServer server; 35 final AnalysisServer server;
38 36
39 /** 37 /**
40 * The [SearchEngine] for this server.
41 */
42 SearchEngine searchEngine;
43
44 /**
45 * The next completion response id. 38 * The next completion response id.
46 */ 39 */
47 int _nextCompletionId = 0; 40 int _nextCompletionId = 0;
48 41
49 /** 42 /**
50 * The completion manager for most recent [Source] and [AnalysisContext],
51 * or `null` if none.
52 */
53 CompletionManager _manager;
54
55 /**
56 * The subscription for the cached context's source change stream.
57 */
58 StreamSubscription<SourcesChangedEvent> _sourcesChangedSubscription;
59
60 /**
61 * Code completion performance for the last completion operation. 43 * Code completion performance for the last completion operation.
62 */ 44 */
63 CompletionPerformance performance; 45 CompletionPerformance performance;
64 46
65 /** 47 /**
66 * A list of code completion performance measurements for the latest 48 * A list of code completion performance measurements for the latest
67 * completion operation up to [performanceListMaxLength] measurements. 49 * completion operation up to [performanceListMaxLength] measurements.
68 */ 50 */
69 final List<CompletionPerformance> performanceList = 51 final List<CompletionPerformance> performanceList =
70 new List<CompletionPerformance>(); 52 new List<CompletionPerformance>();
71 53
72 /** 54 /**
73 * Performance for the last priority change event. 55 * Performance for the last priority change event.
74 */ 56 */
75 CompletionPerformance computeCachePerformance; 57 CompletionPerformance computeCachePerformance;
76 58
77 /** 59 /**
78 * Initialize a new request handler for the given [server]. 60 * Initialize a new request handler for the given [server].
79 */ 61 */
80 CompletionDomainHandler(this.server) { 62 CompletionDomainHandler(this.server);
81 server.onContextsChanged.listen(contextsChanged);
82 server.onPriorityChange.listen(priorityChanged);
83 searchEngine = server.searchEngine;
84 }
85
86 /**
87 * Return the completion manager for most recent [Source] and [AnalysisContext ],
88 * or `null` if none.
89 */
90 CompletionManager get manager => _manager;
91 63
92 /** 64 /**
93 * Return the [CompletionManager] for the given [context] and [source], 65 * Return the [CompletionManager] for the given [context] and [source],
94 * creating a new manager or returning an existing manager as necessary. 66 * creating a new manager or returning an existing manager as necessary.
95 */ 67 */
96 CompletionManager completionManagerFor( 68 CompletionManager completionManagerFor(
97 AnalysisContext context, Source source) { 69 AnalysisContext context, Source source) {
98 if (_manager != null) { 70 return createCompletionManager(server, context, source);
99 if (_manager.context == context && _manager.source == source) {
100 return _manager;
101 }
102 _discardManager();
103 }
104 _manager = createCompletionManager(server, context, source);
105 if (context != null) {
106 _sourcesChangedSubscription =
107 context.onSourcesChanged.listen(sourcesChanged);
108 }
109 return _manager;
110 }
111
112 /**
113 * If the context associated with the cache has changed or been removed
114 * then discard the cache.
115 */
116 void contextsChanged(ContextsChangedEvent event) {
117 if (_manager != null) {
118 AnalysisContext context = _manager.context;
119 if (event.changed.contains(context) || event.removed.contains(context)) {
120 _discardManager();
121 }
122 }
123 } 71 }
124 72
125 CompletionManager createCompletionManager( 73 CompletionManager createCompletionManager(
126 AnalysisServer server, AnalysisContext context, Source source) { 74 AnalysisServer server, AnalysisContext context, Source source) {
127 return new CompletionManager.create(context, source, server.searchEngine, 75 return new CompletionManager.create(context, source, server.searchEngine,
128 server.serverPlugin.completionContributors); 76 server.serverPlugin.completionContributors);
129 } 77 }
130 78
131 @override 79 @override
132 Response handleRequest(Request request) { 80 Response handleRequest(Request request) {
133 if (searchEngine == null) { 81 if (server.searchEngine == null) {
134 return new Response.noIndexGenerated(request); 82 return new Response.noIndexGenerated(request);
135 } 83 }
136 return runZoned(() { 84 return runZoned(() {
137 try { 85 try {
138 String requestName = request.method; 86 String requestName = request.method;
139 if (requestName == COMPLETION_GET_SUGGESTIONS) { 87 if (requestName == COMPLETION_GET_SUGGESTIONS) {
140 return processRequest(request); 88 return processRequest(request);
141 } 89 }
142 } on RequestFailure catch (exception) { 90 } on RequestFailure catch (exception) {
143 return exception.response; 91 return exception.response;
144 } 92 }
145 return null; 93 return null;
146 }, onError: (exception, stackTrace) { 94 }, onError: (exception, stackTrace) {
147 server.sendServerErrorNotification( 95 server.sendServerErrorNotification(
148 'Failed to handle completion domain request: ${request.toJson()}', 96 'Failed to handle completion domain request: ${request.toJson()}',
149 exception, 97 exception,
150 stackTrace); 98 stackTrace);
151 }); 99 });
152 } 100 }
153 101
154 /** 102 /**
155 * If the set the priority files has changed, then pre-cache completion
156 * information related to the first priority file.
157 */
158 void priorityChanged(PriorityChangeEvent event) {
159 Source source = event.firstSource;
160 CompletionPerformance performance = new CompletionPerformance();
161 computeCachePerformance = performance;
162 if (source == null) {
163 performance.complete('priorityChanged caching: no source');
164 return;
165 }
166 performance.source = source;
167 AnalysisContext context = server.getAnalysisContextForSource(source);
168 if (context != null) {
169 String computeTag = 'computeCache';
170 performance.logStartTime(computeTag);
171 CompletionManager manager = completionManagerFor(context, source);
172 manager.computeCache().catchError((_) => false).then((bool success) {
173 performance.logElapseTime(computeTag);
174 performance.complete('priorityChanged caching: $success');
175 });
176 }
177 }
178
179 /**
180 * Process a `completion.getSuggestions` request. 103 * Process a `completion.getSuggestions` request.
181 */ 104 */
182 Response processRequest(Request request, [CompletionManager manager]) { 105 Response processRequest(Request request, [CompletionManager manager]) {
183 performance = new CompletionPerformance(); 106 performance = new CompletionPerformance();
184 107
185 // extract and validate params 108 // extract and validate params
186 CompletionGetSuggestionsParams params = 109 CompletionGetSuggestionsParams params =
187 new CompletionGetSuggestionsParams.fromRequest(request); 110 new CompletionGetSuggestionsParams.fromRequest(request);
188 ContextSourcePair contextSource = server.getContextSourcePair(params.file); 111 ContextSourcePair contextSource = server.getContextSourcePair(params.file);
189 AnalysisContext context = contextSource.context; 112 AnalysisContext context = contextSource.context;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 174
252 /** 175 /**
253 * Send completion notification results. 176 * Send completion notification results.
254 */ 177 */
255 void sendCompletionNotification(String completionId, int replacementOffset, 178 void sendCompletionNotification(String completionId, int replacementOffset,
256 int replacementLength, Iterable<CompletionSuggestion> results) { 179 int replacementLength, Iterable<CompletionSuggestion> results) {
257 server.sendNotification(new CompletionResultsParams( 180 server.sendNotification(new CompletionResultsParams(
258 completionId, replacementOffset, replacementLength, results, true) 181 completionId, replacementOffset, replacementLength, results, true)
259 .toNotification()); 182 .toNotification());
260 } 183 }
261
262 /**
263 * Discard the cache if a source other than the source referenced by
264 * the cache changes or if any source is added, removed, or deleted.
265 */
266 void sourcesChanged(SourcesChangedEvent event) {
267 bool shouldDiscardManager(SourcesChangedEvent event) {
268 if (_manager == null) {
269 return false;
270 }
271 if (event.wereSourcesAdded || event.wereSourcesRemovedOrDeleted) {
272 return true;
273 }
274 var changedSources = event.changedSources;
275 return changedSources.length > 2 ||
276 (changedSources.length == 1 &&
277 !changedSources.contains(_manager.source));
278 }
279
280 if (shouldDiscardManager(event)) {
281 _discardManager();
282 }
283 }
284
285 /**
286 * Discard the sourcesChanged subscription if any
287 */
288 void _discardManager() {
289 if (_sourcesChangedSubscription != null) {
290 _sourcesChangedSubscription.cancel();
291 _sourcesChangedSubscription = null;
292 }
293 if (_manager != null) {
294 _manager.dispose();
295 _manager = null;
296 }
297 }
298 } 184 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698