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 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
103 Duration get timeout => _timeout; | 103 Duration get timeout => _timeout; |
104 Duration _timeout = new Duration(seconds: 5); | 104 Duration _timeout = new Duration(seconds: 5); |
105 set timeout(Duration duration) { | 105 set timeout(Duration duration) { |
106 _timeout = duration; | 106 _timeout = duration; |
107 heartbeat(); | 107 heartbeat(); |
108 } | 108 } |
109 | 109 |
110 /// The timer for keeping track of task timeouts. This may be null. | 110 /// The timer for keeping track of task timeouts. This may be null. |
111 Timer _timeoutTimer; | 111 Timer _timeoutTimer; |
112 | 112 |
| 113 /// If `true`, then new [Task]s will capture the current stack trace before |
| 114 /// running. This can be set to `false` to speed up running tests since |
| 115 /// capturing stack traces is currently quite slow. Even when set to `false`, |
| 116 /// stack traces from *thrown* exceptions will be caught. This only disables |
| 117 /// the eager collection of stack traces *before* an error occurs. Defaults |
| 118 /// to `true`. |
| 119 bool captureStackTraces = true; |
| 120 |
113 /// Creates a new schedule with empty task queues. | 121 /// Creates a new schedule with empty task queues. |
114 Schedule() { | 122 Schedule() { |
115 _tasks = new TaskQueue._("tasks", this); | 123 _tasks = new TaskQueue._("tasks", this); |
116 _onComplete = new TaskQueue._("onComplete", this); | 124 _onComplete = new TaskQueue._("onComplete", this); |
117 _onException = new TaskQueue._("onException", this); | 125 _onException = new TaskQueue._("onException", this); |
118 _currentQueue = _tasks; | 126 _currentQueue = _tasks; |
119 | 127 |
120 heartbeat(); | 128 heartbeat(); |
121 } | 129 } |
122 | 130 |
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 currentQueue._signalTimeout(new ScheduleError.from(this, "The schedule " | 310 currentQueue._signalTimeout(new ScheduleError.from(this, "The schedule " |
303 "timed out after $_timeout of inactivity.")); | 311 "timed out after $_timeout of inactivity.")); |
304 }); | 312 }); |
305 } | 313 } |
306 } | 314 } |
307 | 315 |
308 /// Register an error in the schedule's error list. This ensures that there | 316 /// Register an error in the schedule's error list. This ensures that there |
309 /// are no duplicate errors, and that all errors are wrapped in | 317 /// are no duplicate errors, and that all errors are wrapped in |
310 /// [ScheduleError]. | 318 /// [ScheduleError]. |
311 void _addError(error) { | 319 void _addError(error) { |
312 if (errors.contains(error)) return; | 320 if (error is ScheduleError && errors.contains(error)) return; |
313 errors.add(new ScheduleError.from(this, error)); | 321 errors.add(new ScheduleError.from(this, error)); |
314 } | 322 } |
315 } | 323 } |
316 | 324 |
317 /// An enum of states for a [Schedule]. | 325 /// An enum of states for a [Schedule]. |
318 class ScheduleState { | 326 class ScheduleState { |
319 /// The schedule can have tasks added to its queue, but is not yet running | 327 /// The schedule can have tasks added to its queue, but is not yet running |
320 /// them. | 328 /// them. |
321 static const SET_UP = const ScheduleState._("SET_UP"); | 329 static const SET_UP = const ScheduleState._("SET_UP"); |
322 | 330 |
(...skipping 16 matching lines...) Expand all Loading... |
339 /// A queue of asynchronous tasks to execute in order. | 347 /// A queue of asynchronous tasks to execute in order. |
340 class TaskQueue { | 348 class TaskQueue { |
341 // TODO(nweiz): make this a read-only view when issue 8321 is fixed. | 349 // TODO(nweiz): make this a read-only view when issue 8321 is fixed. |
342 /// The tasks in the queue. | 350 /// The tasks in the queue. |
343 Collection<Task> get contents => _contents; | 351 Collection<Task> get contents => _contents; |
344 final _contents = new Queue<Task>(); | 352 final _contents = new Queue<Task>(); |
345 | 353 |
346 /// The name of the queue, for debugging purposes. | 354 /// The name of the queue, for debugging purposes. |
347 final String name; | 355 final String name; |
348 | 356 |
| 357 /// If `true`, then new [Task]s in this queue will capture the current stack |
| 358 /// trace before running. |
| 359 bool get captureStackTraces => _schedule.captureStackTraces; |
| 360 |
349 /// The [Schedule] that created this queue. | 361 /// The [Schedule] that created this queue. |
350 final Schedule _schedule; | 362 final Schedule _schedule; |
351 | 363 |
352 /// 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 |
353 /// 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 |
354 /// error. | 366 /// error. |
355 ScheduleError _error; | 367 ScheduleError _error; |
356 | 368 |
357 /// The [SubstituteFuture] for the currently-running task in the queue, or | 369 /// The [SubstituteFuture] for the currently-running task in the queue, or |
358 /// null if no task is currently running. | 370 /// null if no task is currently running. |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 Function _wrapAsync(fn(arg), String description) { | 501 Function _wrapAsync(fn(arg), String description) { |
490 assert(_schedule.state == ScheduleState.SET_UP || isRunning); | 502 assert(_schedule.state == ScheduleState.SET_UP || isRunning); |
491 | 503 |
492 // It's possible that the queue timed out before [fn] finished. | 504 // It's possible that the queue timed out before [fn] finished. |
493 bool _timedOut() => | 505 bool _timedOut() => |
494 _schedule.currentQueue != this || pendingCallbacks.isEmpty; | 506 _schedule.currentQueue != this || pendingCallbacks.isEmpty; |
495 | 507 |
496 if (description == null) { | 508 if (description == null) { |
497 description = "Out-of-band operation #${_totalCallbacks}"; | 509 description = "Out-of-band operation #${_totalCallbacks}"; |
498 } | 510 } |
499 var stackString = prefixLines(terseTraceString(new Trace.current())); | 511 |
500 description = "$description\n\nStack trace:\n$stackString"; | 512 if (captureStackTraces) { |
| 513 var stackString = prefixLines(terseTraceString(new Trace.current())); |
| 514 description += "\n\nStack trace:\n$stackString"; |
| 515 } |
| 516 |
501 _totalCallbacks++; | 517 _totalCallbacks++; |
502 | 518 |
503 _pendingCallbacks.add(description); | 519 _pendingCallbacks.add(description); |
504 return (arg) { | 520 return (arg) { |
505 try { | 521 try { |
506 return fn(arg); | 522 return fn(arg); |
507 } catch (e, stackTrace) { | 523 } catch (e, stackTrace) { |
508 var error = new ScheduleError.from( | 524 var error = new ScheduleError.from( |
509 _schedule, e, stackTrace: stackTrace); | 525 _schedule, e, stackTrace: stackTrace); |
510 if (_timedOut()) { | 526 if (_timedOut()) { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
582 return prefixLines(childString, | 598 return prefixLines(childString, |
583 firstPrefix: " $prefix ", prefix: " | "); | 599 firstPrefix: " $prefix ", prefix: " | "); |
584 }).join('\n'); | 600 }).join('\n'); |
585 taskString = '$taskString\n$childrenString'; | 601 taskString = '$taskString\n$childrenString'; |
586 } | 602 } |
587 | 603 |
588 return taskString; | 604 return taskString; |
589 }).join("\n"); | 605 }).join("\n"); |
590 } | 606 } |
591 } | 607 } |
OLD | NEW |