OLD | NEW |
---|---|
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 schedule; | 5 library schedule; |
6 | 6 |
7 import 'dart:async'; | 7 import 'dart:async'; |
8 import 'dart:collection'; | 8 import 'dart:collection'; |
9 | 9 |
10 import 'package:stack_trace/stack_trace.dart'; | 10 import 'package:stack_trace/stack_trace.dart'; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
55 /// Returns the [Task] that's currently executing, or `null` if there is no | 55 /// Returns the [Task] that's currently executing, or `null` if there is no |
56 /// such task. This will be `null` both before the schedule starts running and | 56 /// such task. This will be `null` both before the schedule starts running and |
57 /// after it's finished. | 57 /// after it's finished. |
58 Task get currentTask => _currentTask; | 58 Task get currentTask => _currentTask; |
59 Task _currentTask; | 59 Task _currentTask; |
60 | 60 |
61 /// The current state of the schedule. | 61 /// The current state of the schedule. |
62 ScheduleState get state => _state; | 62 ScheduleState get state => _state; |
63 ScheduleState _state = ScheduleState.SET_UP; | 63 ScheduleState _state = ScheduleState.SET_UP; |
64 | 64 |
65 // TODO(nweiz): make this a read-only view once issue 8321 is fixed. | |
66 /// Errors thrown by the task queues. | 65 /// Errors thrown by the task queues. |
67 /// | 66 /// |
68 /// When running tasks in [tasks], this will always be empty. If an error | 67 /// When running tasks in [tasks], this will always be empty. If an error |
69 /// occurs in [tasks], it will be added to this list and then [onException] | 68 /// occurs in [tasks], it will be added to this list and then [onException] |
70 /// will be run. If an error occurs there as well, it will be added to this | 69 /// will be run. If an error occurs there as well, it will be added to this |
71 /// list and [onComplete] will be run. Errors thrown during [onComplete] will | 70 /// list and [onComplete] will be run. Errors thrown during [onComplete] will |
72 /// also be added to this list, although no scheduled tasks will be run | 71 /// also be added to this list, although no scheduled tasks will be run |
73 /// afterwards. | 72 /// afterwards. |
74 /// | 73 /// |
75 /// Any out-of-band callbacks that throw errors will also have those errors | 74 /// Any out-of-band callbacks that throw errors will also have those errors |
76 /// added to this list. | 75 /// added to this list. |
77 final errors = <ScheduleError>[]; | 76 List<ScheduleError> get errors => |
Bob Nystrom
2013/04/22 22:11:40
Is it worth exposing UnmodifiableListView in the t
nweiz
2013/04/22 22:46:40
I don't think so. I want the flexibility to swap o
| |
77 new UnmodifiableListView<ScheduleError>(_errors); | |
78 final _errors = <ScheduleError>[]; | |
78 | 79 |
79 // TODO(nweiz): make this a read-only view once issue 8321 is fixed. | |
80 /// Additional debugging info registered via [addDebugInfo]. | 80 /// Additional debugging info registered via [addDebugInfo]. |
81 final debugInfo = <String>[]; | 81 List<String> get debugInfo => new UnmodifiableListView<String>(_debugInfo); |
82 final _debugInfo = <String>[]; | |
82 | 83 |
83 /// The task queue that's currently being run. One of [tasks], [onException], | 84 /// The task queue that's currently being run. One of [tasks], [onException], |
84 /// or [onComplete]. This starts as [tasks], and can only be `null` after the | 85 /// or [onComplete]. This starts as [tasks], and can only be `null` after the |
85 /// schedule is done. | 86 /// schedule is done. |
86 TaskQueue get currentQueue => | 87 TaskQueue get currentQueue => |
87 _state == ScheduleState.DONE ? null : _currentQueue; | 88 _state == ScheduleState.DONE ? null : _currentQueue; |
88 TaskQueue _currentQueue; | 89 TaskQueue _currentQueue; |
89 | 90 |
90 /// The time to wait before terminating a task queue for inactivity. Defaults | 91 /// The time to wait before terminating a task queue for inactivity. Defaults |
91 /// to 5 seconds. This can be set to `null` to disable timeouts entirely. Note | 92 /// to 5 seconds. This can be set to `null` to disable timeouts entirely. Note |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
205 throw scheduleError; | 206 throw scheduleError; |
206 } else { | 207 } else { |
207 _currentQueue._signalError(scheduleError); | 208 _currentQueue._signalError(scheduleError); |
208 } | 209 } |
209 } | 210 } |
210 | 211 |
211 /// Adds [info] to the debugging output that will be printed if the test | 212 /// Adds [info] to the debugging output that will be printed if the test |
212 /// fails. Unlike [signalError], this won't cause the test to fail, nor will | 213 /// fails. Unlike [signalError], this won't cause the test to fail, nor will |
213 /// it short-circuit the current [TaskQueue]; it's just useful for providing | 214 /// it short-circuit the current [TaskQueue]; it's just useful for providing |
214 /// additional information that may not fit cleanly into an existing error. | 215 /// additional information that may not fit cleanly into an existing error. |
215 void addDebugInfo(String info) => debugInfo.add(info); | 216 void addDebugInfo(String info) => _debugInfo.add(info); |
216 | 217 |
217 /// Notifies the schedule of an error that occurred in a task or out-of-band | 218 /// Notifies the schedule of an error that occurred in a task or out-of-band |
218 /// callback after the appropriate queue has timed out. If this schedule is | 219 /// callback after the appropriate queue has timed out. If this schedule is |
219 /// still running, the error will be added to the errors list to be shown | 220 /// still running, the error will be added to the errors list to be shown |
220 /// along with the timeout error; otherwise, a top-level error will be thrown. | 221 /// along with the timeout error; otherwise, a top-level error will be thrown. |
221 void _signalPostTimeoutError(error, [stackTrace]) { | 222 void _signalPostTimeoutError(error, [stackTrace]) { |
222 var scheduleError = new ScheduleError.from(this, error, | 223 var scheduleError = new ScheduleError.from(this, error, |
223 stackTrace: stackTrace); | 224 stackTrace: stackTrace); |
224 _addError(scheduleError); | 225 _addError(scheduleError); |
225 if (_state == ScheduleState.DONE) { | 226 if (_state == ScheduleState.DONE) { |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
311 "timed out after $_timeout of inactivity.")); | 312 "timed out after $_timeout of inactivity.")); |
312 }); | 313 }); |
313 } | 314 } |
314 } | 315 } |
315 | 316 |
316 /// Register an error in the schedule's error list. This ensures that there | 317 /// Register an error in the schedule's error list. This ensures that there |
317 /// are no duplicate errors, and that all errors are wrapped in | 318 /// are no duplicate errors, and that all errors are wrapped in |
318 /// [ScheduleError]. | 319 /// [ScheduleError]. |
319 void _addError(error) { | 320 void _addError(error) { |
320 if (error is ScheduleError && errors.contains(error)) return; | 321 if (error is ScheduleError && errors.contains(error)) return; |
321 errors.add(new ScheduleError.from(this, error)); | 322 _errors.add(new ScheduleError.from(this, error)); |
322 } | 323 } |
323 } | 324 } |
324 | 325 |
325 /// An enum of states for a [Schedule]. | 326 /// An enum of states for a [Schedule]. |
326 class ScheduleState { | 327 class ScheduleState { |
327 /// The schedule can have tasks added to its queue, but is not yet running | 328 /// The schedule can have tasks added to its queue, but is not yet running |
328 /// them. | 329 /// them. |
329 static const SET_UP = const ScheduleState._("SET_UP"); | 330 static const SET_UP = const ScheduleState._("SET_UP"); |
330 | 331 |
331 /// The schedule is actively running tasks. This includes running tasks in | 332 /// The schedule is actively running tasks. This includes running tasks in |
332 /// [Schedule.onException] and [Schedule.onComplete]. | 333 /// [Schedule.onException] and [Schedule.onComplete]. |
333 static const RUNNING = const ScheduleState._("RUNNING"); | 334 static const RUNNING = const ScheduleState._("RUNNING"); |
334 | 335 |
335 /// The schedule has finished running all its tasks, either successfully or | 336 /// The schedule has finished running all its tasks, either successfully or |
336 /// with an error. | 337 /// with an error. |
337 static const DONE = const ScheduleState._("DONE"); | 338 static const DONE = const ScheduleState._("DONE"); |
338 | 339 |
339 /// The name of the state. | 340 /// The name of the state. |
340 final String name; | 341 final String name; |
341 | 342 |
342 const ScheduleState._(this.name); | 343 const ScheduleState._(this.name); |
343 | 344 |
344 String toString() => name; | 345 String toString() => name; |
345 } | 346 } |
346 | 347 |
347 /// A queue of asynchronous tasks to execute in order. | 348 /// A queue of asynchronous tasks to execute in order. |
348 class TaskQueue { | 349 class TaskQueue { |
349 // TODO(nweiz): make this a read-only view when issue 8321 is fixed. | |
350 /// The tasks in the queue. | 350 /// The tasks in the queue. |
351 Iterable<Task> get contents => _contents; | 351 List<Task> get contents => new UnmodifiableListView<Task>(_contents); |
352 final _contents = new Queue<Task>(); | 352 final _contents = new Queue<Task>(); |
353 | 353 |
354 /// The name of the queue, for debugging purposes. | 354 /// The name of the queue, for debugging purposes. |
355 final String name; | 355 final String name; |
356 | 356 |
357 /// If `true`, then new [Task]s in this queue will capture the current stack | 357 /// If `true`, then new [Task]s in this queue will capture the current stack |
358 /// trace before running. | 358 /// trace before running. |
359 bool get captureStackTraces => _schedule.captureStackTraces; | 359 bool get captureStackTraces => _schedule.captureStackTraces; |
360 | 360 |
361 /// The [Schedule] that created this queue. | 361 /// The [Schedule] that created this queue. |
362 final Schedule _schedule; | 362 final Schedule _schedule; |
363 | 363 |
364 /// An out-of-band error signaled by [_schedule]. If this is non-null, it | 364 /// An out-of-band error signaled by [_schedule]. If this is non-null, it |
365 /// indicates that the queue should stop as soon as possible and re-throw this | 365 /// indicates that the queue should stop as soon as possible and re-throw this |
366 /// error. | 366 /// error. |
367 ScheduleError _error; | 367 ScheduleError _error; |
368 | 368 |
369 /// The [SubstituteFuture] for the currently-running task in the queue, or | 369 /// The [SubstituteFuture] for the currently-running task in the queue, or |
370 /// null if no task is currently running. | 370 /// null if no task is currently running. |
371 SubstituteFuture _taskFuture; | 371 SubstituteFuture _taskFuture; |
372 | 372 |
373 /// The toal number of out-of-band callbacks that have been registered on | 373 /// The toal number of out-of-band callbacks that have been registered on |
374 /// [this]. | 374 /// [this]. |
375 int _totalCallbacks = 0; | 375 int _totalCallbacks = 0; |
376 | 376 |
377 /// Whether to stop running after the current task. | 377 /// Whether to stop running after the current task. |
378 bool _aborted = false; | 378 bool _aborted = false; |
379 | 379 |
380 // TODO(nweiz): make this a read-only view when issue 8321 is fixed. | |
381 /// The descriptions of all callbacks that are blocking the completion of | 380 /// The descriptions of all callbacks that are blocking the completion of |
382 /// [this]. | 381 /// [this]. |
383 Iterable<String> get pendingCallbacks => _pendingCallbacks; | 382 List<String> get pendingCallbacks => |
383 new UnmodifiableListView<String>(_pendingCallbacks); | |
384 final _pendingCallbacks = new Queue<String>(); | 384 final _pendingCallbacks = new Queue<String>(); |
385 | 385 |
386 /// A completer that will be completed once [_pendingCallbacks] becomes empty | 386 /// A completer that will be completed once [_pendingCallbacks] becomes empty |
387 /// after the queue finishes running its tasks. | 387 /// after the queue finishes running its tasks. |
388 Future get _noPendingCallbacks => _noPendingCallbacksCompleter.future; | 388 Future get _noPendingCallbacks => _noPendingCallbacksCompleter.future; |
389 final Completer _noPendingCallbacksCompleter = new Completer(); | 389 final Completer _noPendingCallbacksCompleter = new Completer(); |
390 | 390 |
391 /// A [Future] that completes when the tasks in [this] are all complete. If an | 391 /// A [Future] that completes when the tasks in [this] are all complete. If an |
392 /// error occurs while running this queue, the returned [Future] will complete | 392 /// error occurs while running this queue, the returned [Future] will complete |
393 /// with that error. | 393 /// with that error. |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
598 return prefixLines(childString, | 598 return prefixLines(childString, |
599 firstPrefix: " $prefix ", prefix: " | "); | 599 firstPrefix: " $prefix ", prefix: " | "); |
600 }).join('\n'); | 600 }).join('\n'); |
601 taskString = '$taskString\n$childrenString'; | 601 taskString = '$taskString\n$childrenString'; |
602 } | 602 } |
603 | 603 |
604 return taskString; | 604 return taskString; |
605 }).join("\n"); | 605 }).join("\n"); |
606 } | 606 } |
607 } | 607 } |
OLD | NEW |