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

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

Issue 246603005: Use AnalysisServer.running only to track whether server has been shut down. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 8 months 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 | Annotate | Revision Log
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 analysis.server; 5 library analysis.server;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 8
9 import 'package:analysis_server/src/analysis_logger.dart'; 9 import 'package:analysis_server/src/analysis_logger.dart';
10 import 'package:analysis_server/src/channel.dart'; 10 import 'package:analysis_server/src/channel.dart';
(...skipping 25 matching lines...) Expand all
36 */ 36 */
37 static const String CONNECTED_NOTIFICATION = 'server.connected'; 37 static const String CONNECTED_NOTIFICATION = 'server.connected';
38 38
39 /** 39 /**
40 * The channel from which requests are received and to which responses should 40 * The channel from which requests are received and to which responses should
41 * be sent. 41 * be sent.
42 */ 42 */
43 final ServerCommunicationChannel channel; 43 final ServerCommunicationChannel channel;
44 44
45 /** 45 /**
46 * A flag indicating whether the server is running. 46 * A flag indicating whether the server is running. When false, contexts
47 * will no longer be added to [contextWorkQueue], and [performTask] will
48 * discard any tasks it finds on [contextWorkQueue].
47 */ 49 */
48 bool running; 50 bool running;
49 51
50 /** 52 /**
51 * A list of the request handlers used to handle the requests sent to this 53 * A list of the request handlers used to handle the requests sent to this
52 * server. 54 * server.
53 */ 55 */
54 List<RequestHandler> handlers; 56 List<RequestHandler> handlers;
55 57
56 /** 58 /**
57 * A table mapping context id's to the analysis contexts associated with them. 59 * A table mapping context id's to the analysis contexts associated with them.
58 */ 60 */
59 final Map<String, AnalysisContext> contextMap = new Map<String, AnalysisContex t>(); 61 final Map<String, AnalysisContext> contextMap = new Map<String, AnalysisContex t>();
60 62
61 /** 63 /**
62 * A list of the analysis contexts for which analysis work needs to be 64 * A list of the analysis contexts for which analysis work needs to be
63 * performed. 65 * performed.
66 *
67 * Invariant: when this list is non-empty, there is exactly one pending call
68 * to [performTask] on the event queue. When this list is empty, there are
69 * no calls to [performTask] on the event queue.
64 */ 70 */
65 final List<AnalysisContext> contextWorkQueue = new List<AnalysisContext>(); 71 final List<AnalysisContext> contextWorkQueue = new List<AnalysisContext>();
66 72
67 /** 73 /**
68 * Initialize a newly created server to receive requests from and send 74 * Initialize a newly created server to receive requests from and send
69 * responses to the given [channel]. 75 * responses to the given [channel].
70 */ 76 */
71 AnalysisServer(this.channel) { 77 AnalysisServer(this.channel) {
72 AnalysisEngine.instance.logger = new AnalysisLogger(); 78 AnalysisEngine.instance.logger = new AnalysisLogger();
73 running = true; 79 running = true;
74 Notification notification = new Notification(CONNECTED_NOTIFICATION); 80 Notification notification = new Notification(CONNECTED_NOTIFICATION);
75 channel.sendNotification(notification); 81 channel.sendNotification(notification);
76 channel.listen(handleRequest, onDone: done, onError: error); 82 channel.listen(handleRequest, onDone: done, onError: error);
77 } 83 }
78 84
79 /** 85 /**
80 * Add the given [context] to the list of analysis contexts for which analysis 86 * If [running] is true, add the given [context] to the list of analysis
81 * work needs to be performed. Ensure that the work will be performed. 87 * contexts for which analysis work needs to be performed, and ensure that
88 * the work will be performed.
82 */ 89 */
83 void addContextToWorkQueue(AnalysisContext context) { 90 void addContextToWorkQueue(AnalysisContext context) {
91 if (!running) {
92 return;
93 }
84 if (!contextWorkQueue.contains(context)) { 94 if (!contextWorkQueue.contains(context)) {
85 contextWorkQueue.add(context); 95 contextWorkQueue.add(context);
86 run(); 96 if (contextWorkQueue.length == 1) {
97 // Work queue was previously empty, so schedule analysis.
98 _scheduleTask();
99 }
87 } 100 }
88 } 101 }
89 102
90 /** 103 /**
91 * The socket from which requests are being read has been closed. 104 * The socket from which requests are being read has been closed.
92 */ 105 */
93 void done() { 106 void done() {
94 running = false; 107 running = false;
95 } 108 }
96 109
(...skipping 24 matching lines...) Expand all
121 } 134 }
122 channel.sendResponse(new Response.unknownRequest(request)); 135 channel.sendResponse(new Response.unknownRequest(request));
123 } 136 }
124 137
125 /** 138 /**
126 * Perform the next available task. If a request was received that has not yet 139 * Perform the next available task. If a request was received that has not yet
127 * been performed, perform it next. Otherwise, look for some analysis that 140 * been performed, perform it next. Otherwise, look for some analysis that
128 * needs to be done and do that. Otherwise, do nothing. 141 * needs to be done and do that. Otherwise, do nothing.
129 */ 142 */
130 void performTask() { 143 void performTask() {
144 if (!running) {
145 // An error has occurred, or the connection to the client has been
146 // closed, since performTask() was scheduled on the event queue. So
147 // don't do any analysis. Instead clear the work queue.
148 contextWorkQueue.clear();
149 }
150 if (contextWorkQueue.isEmpty) {
151 // Nothing to do.
152 return;
153 }
131 // 154 //
132 // Look for a context that has work to be done and then perform one task. 155 // Look for a context that has work to be done and then perform one task.
133 // 156 //
134 if (!contextWorkQueue.isEmpty) { 157 List<ChangeNotice> notices = null;
158 try {
135 AnalysisContext context = contextWorkQueue[0]; 159 AnalysisContext context = contextWorkQueue[0];
136 AnalysisResult result = context.performAnalysisTask(); 160 AnalysisResult result = context.performAnalysisTask();
137 List<ChangeNotice> notices = result.changeNotices; 161 notices = result.changeNotices;
162 } finally {
138 if (notices == null) { 163 if (notices == null) {
164 // Either we have no more work to do for this context, or there was an
165 // unhandled exception trying to perform the analysis. In either case,
166 // remove the context form the work queue so we won't try to do more
167 // analysis on it.
139 contextWorkQueue.removeAt(0); 168 contextWorkQueue.removeAt(0);
140 } else { //if (context.analysisOptions.provideErrors) { 169 }
141 sendNotices(notices); 170 //
171 // Schedule this method to be run again if there is any more work to be
172 // done.
173 //
174 if (!contextWorkQueue.isEmpty) {
175 _scheduleTask();
142 } 176 }
143 } 177 }
144 // 178 if (notices != null) {
145 // Schedule this method to be run again if there is any more work to be done . 179 sendNotices(notices);
146 //
147 if (contextWorkQueue.isEmpty) {
148 running = false;
149 } else {
150 new Future(performTask).catchError((ex, st) {
151 AnalysisEngine.instance.logger.logError("${ex}\n${st}");
152 });
153 } 180 }
154 } 181 }
155 182
156 /** 183 /**
157 * Send the information in the given list of notices back to the client. 184 * Send the information in the given list of notices back to the client.
158 */ 185 */
159 void sendNotices(List<ChangeNotice> notices) { 186 void sendNotices(List<ChangeNotice> notices) {
160 for (int i = 0; i < notices.length; i++) { 187 for (int i = 0; i < notices.length; i++) {
161 ChangeNotice notice = notices[i]; 188 ChangeNotice notice = notices[i];
162 Notification notification = new Notification(ERROR_NOTIFICATION_NAME); 189 Notification notification = new Notification(ERROR_NOTIFICATION_NAME);
163 notification.setParameter(SOURCE_PARAM, notice.source.encoding); 190 notification.setParameter(SOURCE_PARAM, notice.source.encoding);
164 notification.setParameter(ERRORS_PARAM, notice.errors); 191 notification.setParameter(ERRORS_PARAM, notice.errors);
165 sendNotification(notification); 192 sendNotification(notification);
166 } 193 }
167 } 194 }
168 195
169 /** 196 /**
170 * Perform the tasks that are waiting for execution until the server is shut
171 * down.
172 */
173 void run() {
174 if (!running) {
175 running = true;
176 new Future(performTask).catchError((exception, stackTrace) {
177 AnalysisEngine.instance.logger.logError(exception);
178 });
179 }
180 }
181
182 /**
183 * Send the given [notification] to the client. 197 * Send the given [notification] to the client.
184 */ 198 */
185 void sendNotification(Notification notification) { 199 void sendNotification(Notification notification) {
186 channel.sendNotification(notification); 200 channel.sendNotification(notification);
187 } 201 }
202
203 void _scheduleTask() {
204 new Future(performTask).catchError((ex, st) {
205 AnalysisEngine.instance.logger.logError("${ex}\n${st}");
206 });
207 }
188 } 208 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/lib/src/socket_server.dart » ('j') | pkg/analysis_server/test/mocks.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698