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

Side by Side Diff: pkg/scheduled_test/lib/src/task.dart

Issue 812253002: Delete a bunch of packages that are now on GitHub. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Un-delete http Created 6 years 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
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 library task;
6
7 import 'dart:async';
8 import 'dart:collection';
9
10 import 'package:stack_trace/stack_trace.dart';
11
12 import 'future_group.dart';
13 import 'schedule.dart';
14 import 'utils.dart';
15
16 typedef Future TaskBody();
17
18 /// A single task to be run as part of a [TaskQueue].
19 ///
20 /// There are two levels of tasks. **Top-level tasks** are created by calling
21 /// [TaskQueue.schedule] before the queue in question is running. They're run in
22 /// sequence as part of that [TaskQueue]. **Nested tasks** are created by
23 /// calling [TaskQueue.schedule] once the queue is already running, and are run
24 /// in parallel as part of a top-level task.
25 class Task {
26 /// The queue to which this [Task] belongs.
27 final TaskQueue queue;
28
29 /// Child tasks that have been spawned while running this task. This will be
30 /// empty if this task is a nested task.
31 List<Task> get children => new UnmodifiableListView(_children);
32 final _children = new Queue<Task>();
33
34 /// A [FutureGroup] that will complete once all current child tasks are
35 /// finished running. This will be null if no child tasks are currently
36 /// running.
37 FutureGroup _childGroup;
38
39 /// A description of this task. Used for debugging. May be `null`.
40 final String description;
41
42 /// The parent task, if this is a nested task that was started while another
43 /// task was running. This will be `null` for top-level tasks.
44 final Task parent;
45
46 /// The body of the task.
47 TaskBody fn;
48
49 /// The current state of [this].
50 TaskState get state => _state;
51 var _state = TaskState.WAITING;
52
53 /// The identifier of the task. For top-level tasks, this is the index of the
54 /// task within [queue]; for nested tasks, this is the index within
55 /// [parent.children]. It's used for debugging when [description] isn't
56 /// provided.
57 int _id;
58
59 /// A Future that will complete to the return value of [fn] once this task
60 /// finishes running.
61 Future get result => _resultCompleter.future;
62 final _resultCompleter = new Completer();
63
64 final Chain stackChain;
65
66 Task(fn(), String description, TaskQueue queue)
67 : this._(fn, description, queue, null, queue.contents.length);
68
69 Task._child(fn(), String description, Task parent)
70 : this._(fn, description, parent.queue, parent, parent.children.length);
71
72 Task._(fn(), this.description, TaskQueue queue, this.parent, this._id)
73 : queue = queue,
74 stackChain = new Chain.current() {
75 this.fn = () {
76 if (state != TaskState.WAITING) {
77 throw new StateError("Can't run $state task '$this'.");
78 }
79
80 _state = TaskState.RUNNING;
81 var future = new Future.value().then((_) => fn())
82 .whenComplete(() {
83 if (_childGroup == null || _childGroup.completed) return null;
84 return _childGroup.future;
85 });
86 chainToCompleter(future, _resultCompleter);
87 return future;
88 };
89
90 // If the parent queue experiences an error before this task has started
91 // running, pipe that error out through [result]. This ensures that we don't
92 // get deadlocked by something like `expect(schedule(...), completes)`.
93 queue.onTasksComplete.catchError((e) {
94 if (state == TaskState.WAITING) _resultCompleter.completeError(e);
95 });
96
97 // catchError makes sure any error thrown by fn isn't top-leveled by virtue
98 // of being passed to the result future.
99 result.then((_) {
100 _state = TaskState.SUCCESS;
101 }).catchError((e) {
102 _state = TaskState.ERROR;
103 throw e;
104 }).catchError((_) {});
105 }
106
107 /// Run [fn] as a child of this task. Returns a Future that will complete with
108 /// the result of the child task. This task will not complete until [fn] has
109 /// finished.
110 Future runChild(fn(), String description) {
111 var task = new Task._child(fn, description, this);
112 _children.add(task);
113 if (_childGroup == null || _childGroup.completed) {
114 _childGroup = new FutureGroup();
115 }
116 // Ignore errors in the FutureGroup; they'll get picked up via wrapFuture,
117 // and we don't want them to short-circuit the other Futures.
118 _childGroup.add(task.result.catchError((_) {}));
119 task.fn();
120 return task.result;
121 }
122
123 String toString() => description == null ? "#$_id" : description;
124
125 String toStringWithStackTrace() {
126 var stackString = prefixLines(terseTraceString(stackChain));
127 return "$this\n\nStack chain:\n$stackString";
128 }
129
130 /// Returns a detailed representation of [queue] with this task highlighted.
131 String generateTree() => queue.generateTree(this);
132 }
133
134 /// An enum of states for a [Task].
135 class TaskState {
136 /// The task is waiting to be run.
137 static const WAITING = const TaskState._("WAITING");
138
139 /// The task is currently running.
140 static const RUNNING = const TaskState._("RUNNING");
141
142 /// The task has finished running successfully.
143 static const SUCCESS = const TaskState._("SUCCESS");
144
145 /// The task has finished running with an error.
146 static const ERROR = const TaskState._("ERROR");
147
148 /// The name of the state.
149 final String name;
150
151 /// Whether the state indicates that the task has finished running. This is
152 /// true for both the [SUCCESS] and [ERROR] states.
153 bool get isDone => this == SUCCESS || this == ERROR;
154
155 const TaskState._(this.name);
156
157 String toString() => name;
158 }
OLDNEW
« no previous file with comments | « pkg/scheduled_test/lib/src/substitute_future.dart ('k') | pkg/scheduled_test/lib/src/utils.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698