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

Unified Diff: pkg/scheduled_test/lib/src/task.dart

Issue 12288061: Support nested tasks in scheduled_test. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Code review changes Created 7 years, 10 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/scheduled_test/lib/src/schedule_error.dart ('k') | pkg/scheduled_test/test/scheduled_test_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/scheduled_test/lib/src/task.dart
diff --git a/pkg/scheduled_test/lib/src/task.dart b/pkg/scheduled_test/lib/src/task.dart
index 558a9cd6f065584177e820a9ab7bbc0dde29bfc8..0819bd0e0f14a000f16d4d36cdb3a4b0574f0bba 100644
--- a/pkg/scheduled_test/lib/src/task.dart
+++ b/pkg/scheduled_test/lib/src/task.dart
@@ -5,25 +5,49 @@
library task;
import 'dart:async';
+import 'dart:collection';
+import 'future_group.dart';
import 'schedule.dart';
import 'utils.dart';
typedef Future TaskBody();
/// A single task to be run as part of a [TaskQueue].
+///
+/// There are two levels of tasks. **Top-level tasks** are created by calling
+/// [TaskQueue.schedule] before the queue in question is running. They're run in
+/// sequence as part of that [TaskQueue]. **Nested tasks** are created by
+/// calling [TaskQueue.schedule] once the queue is already running, and are run
+/// in parallel as part of a top-level task.
class Task {
/// The queue to which this [Task] belongs.
final TaskQueue queue;
+ // TODO(nweiz): make this a read-only view when issue 8321 is fixed.
+ /// Child tasks that have been spawned while running this task. This will be
+ /// empty if this task is a nested task.
+ final children = new Queue<Task>();
+
+ /// A [FutureGroup] that will complete once all current child tasks are
+ /// finished running. This will be null if no child tasks are currently
+ /// running.
+ FutureGroup _childGroup;
+
/// A description of this task. Used for debugging. May be `null`.
final String description;
+ /// The parent task, if this is a nested task that was started while another
+ /// task was running. This will be `null` for top-level tasks.
+ final Task parent;
+
/// The body of the task.
TaskBody fn;
- /// The identifier of the task. This is unique within [queue]. It's used for
- /// debugging when [description] isn't provided.
+ /// The identifier of the task. For top-level tasks, this is the index of the
+ /// task within [queue]; for nested tasks, this is the index within
+ /// [parent.children]. It's used for debugging when [description] isn't
+ /// provided.
int _id;
/// A Future that will complete to the return value of [fn] once this task
@@ -31,10 +55,19 @@ class Task {
Future get result => _resultCompleter.future;
final _resultCompleter = new Completer();
- Task(fn(), this.queue, this.description) {
- _id = this.queue.contents.length;
+ Task(fn(), String description, TaskQueue queue)
+ : this._(fn, description, queue, null, queue.contents.length);
+
+ Task._child(fn(), String description, Task parent)
+ : this._(fn, description, parent.queue, parent, parent.children.length);
+
+ Task._(fn(), this.description, this.queue, this.parent, this._id) {
this.fn = () {
- var future = new Future.immediate(null).then((_) => fn());
+ var future = new Future.immediate(null).then((_) => fn())
+ .whenComplete(() {
+ if (_childGroup == null || _childGroup.completed) return;
+ return _childGroup.future;
+ });
chainToCompleter(future, _resultCompleter);
return future;
};
@@ -44,6 +77,22 @@ class Task {
result.catchError((_) {});
}
+ /// Run [fn] as a child of this task. Returns a Future that will complete with
+ /// the result of the child task. This task will not complete until [fn] has
+ /// finished.
+ Future runChild(fn(), String description) {
+ var task = new Task._child(fn, description, this);
+ children.add(task);
+ if (_childGroup == null || _childGroup.completed) {
+ _childGroup = new FutureGroup();
+ }
+ // Ignore errors in the FutureGroup; they'll get picked up via wrapFuture,
+ // and we don't want them to short-circuit the other Futures.
+ _childGroup.add(task.result.catchError((_) {}));
+ task.fn();
+ return task.result;
+ }
+
String toString() => description == null ? "#$_id" : description;
/// Returns a detailed representation of [queue] with this task highlighted.
« no previous file with comments | « pkg/scheduled_test/lib/src/schedule_error.dart ('k') | pkg/scheduled_test/test/scheduled_test_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698