Chromium Code Reviews| 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 |