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 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 _onComplete = new TaskQueue._("onComplete", this); | 124 _onComplete = new TaskQueue._("onComplete", this); |
125 _onException = new TaskQueue._("onException", this); | 125 _onException = new TaskQueue._("onException", this); |
126 _currentQueue = _tasks; | 126 _currentQueue = _tasks; |
127 | 127 |
128 heartbeat(); | 128 heartbeat(); |
129 } | 129 } |
130 | 130 |
131 /// Sets up this schedule by running [setUp], then runs all the task queues in | 131 /// Sets up this schedule by running [setUp], then runs all the task queues in |
132 /// order. Any errors in [setUp] will cause [onException] to run. | 132 /// order. Any errors in [setUp] will cause [onException] to run. |
133 Future run(void setUp()) { | 133 Future run(void setUp()) { |
134 return new Future.immediate(null).then((_) { | 134 return new Future.value().then((_) { |
135 try { | 135 try { |
136 setUp(); | 136 setUp(); |
137 } catch (e, stackTrace) { | 137 } catch (e, stackTrace) { |
138 // Even though the scheduling failed, we need to run the onException and | 138 // Even though the scheduling failed, we need to run the onException and |
139 // onComplete queues, so we set the schedule state to RUNNING. | 139 // onComplete queues, so we set the schedule state to RUNNING. |
140 _state = ScheduleState.RUNNING; | 140 _state = ScheduleState.RUNNING; |
141 throw new ScheduleError.from(this, e, stackTrace: stackTrace); | 141 throw new ScheduleError.from(this, e, stackTrace: stackTrace); |
142 } | 142 } |
143 | 143 |
144 _state = ScheduleState.RUNNING; | 144 _state = ScheduleState.RUNNING; |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 /// If this is called when this queue is currently running, it will run [fn] | 425 /// If this is called when this queue is currently running, it will run [fn] |
426 /// on the next event loop iteration rather than adding it to a queue--this is | 426 /// on the next event loop iteration rather than adding it to a queue--this is |
427 /// known as a "nested task". The current task will not complete until [fn] | 427 /// known as a "nested task". The current task will not complete until [fn] |
428 /// (and any [Future] it returns) has finished running. Any errors in [fn] | 428 /// (and any [Future] it returns) has finished running. Any errors in [fn] |
429 /// will automatically be handled. Nested tasks run in parallel, unlike | 429 /// will automatically be handled. Nested tasks run in parallel, unlike |
430 /// top-level tasks which run in sequence. | 430 /// top-level tasks which run in sequence. |
431 Future schedule(fn(), [String description]) { | 431 Future schedule(fn(), [String description]) { |
432 if (isRunning) { | 432 if (isRunning) { |
433 var task = _schedule.currentTask; | 433 var task = _schedule.currentTask; |
434 var wrappedFn = () => _schedule.wrapFuture( | 434 var wrappedFn = () => _schedule.wrapFuture( |
435 new Future.immediate(null).then((_) => fn())); | 435 new Future.value().then((_) => fn())); |
436 if (task == null) return wrappedFn(); | 436 if (task == null) return wrappedFn(); |
437 return task.runChild(wrappedFn, description); | 437 return task.runChild(wrappedFn, description); |
438 } | 438 } |
439 | 439 |
440 var task = new Task(() { | 440 var task = new Task(() { |
441 return new Future.of(fn).catchError((e) { | 441 return new Future.sync(fn).catchError((e) { |
442 throw new ScheduleError.from(_schedule, e); | 442 throw new ScheduleError.from(_schedule, e); |
443 }); | 443 }); |
444 }, description, this); | 444 }, description, this); |
445 _contents.add(task); | 445 _contents.add(task); |
446 return task.result; | 446 return task.result; |
447 } | 447 } |
448 | 448 |
449 /// Runs all the tasks in this queue in order. | 449 /// Runs all the tasks in this queue in order. |
450 Future _run() { | 450 Future _run() { |
451 _schedule._currentQueue = this; | 451 _schedule._currentQueue = this; |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
550 | 550 |
551 /// Notifies the queue that it has timed out and it needs to terminate | 551 /// Notifies the queue that it has timed out and it needs to terminate |
552 /// immediately with a timeout error. | 552 /// immediately with a timeout error. |
553 void _signalTimeout(ScheduleError error) { | 553 void _signalTimeout(ScheduleError error) { |
554 _pendingCallbacks.clear(); | 554 _pendingCallbacks.clear(); |
555 if (!isRunningTasks) { | 555 if (!isRunningTasks) { |
556 _noPendingCallbacksCompleter.completeError(error); | 556 _noPendingCallbacksCompleter.completeError(error); |
557 } else if (_taskFuture != null) { | 557 } else if (_taskFuture != null) { |
558 // Catch errors coming off the old task future, in case it completes after | 558 // Catch errors coming off the old task future, in case it completes after |
559 // timing out. | 559 // timing out. |
560 _taskFuture.substitute(new Future.immediateError(error)).catchError((e) { | 560 _taskFuture.substitute(new Future.error(error)).catchError((e) { |
561 _schedule._signalPostTimeoutError(e); | 561 _schedule._signalPostTimeoutError(e); |
562 }); | 562 }); |
563 } else { | 563 } else { |
564 // This branch probably won't be reached, but it's conceivable that the | 564 // This branch probably won't be reached, but it's conceivable that the |
565 // event loop might get pumped when _taskFuture is null but we haven't yet | 565 // event loop might get pumped when _taskFuture is null but we haven't yet |
566 // finished running all the tasks. | 566 // finished running all the tasks. |
567 _signalError(error); | 567 _signalError(error); |
568 } | 568 } |
569 } | 569 } |
570 | 570 |
(...skipping 27 matching lines...) Expand all 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 |