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

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

Issue 12226103: Revert "Add built-in timeouts to scheduled_test." (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: 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/scheduled_test.dart ('k') | pkg/scheduled_test/lib/src/schedule_error.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/scheduled_test/lib/src/schedule.dart
diff --git a/pkg/scheduled_test/lib/src/schedule.dart b/pkg/scheduled_test/lib/src/schedule.dart
index 488acacd5353cd7c343f16c648dfbcef732547c5..d1f5ea340334b53d4c17877011e4a05c6f1e5e66 100644
--- a/pkg/scheduled_test/lib/src/schedule.dart
+++ b/pkg/scheduled_test/lib/src/schedule.dart
@@ -10,7 +10,6 @@ import 'dart:collection';
import 'package:unittest/unittest.dart' as unittest;
import 'schedule_error.dart';
-import 'substitute_future.dart';
import 'task.dart';
/// The schedule of tasks to run for a single test. This has three separate task
@@ -54,9 +53,11 @@ class Schedule {
Task get currentTask => _currentTask;
Task _currentTask;
- /// The current state of the schedule.
- ScheduleState get state => _state;
- ScheduleState _state = ScheduleState.SET_UP;
+ /// Whether the schedule has finished running. This is only set once
+ /// [onComplete] has finished running. It will be set whether or not an
+ /// exception has occurred.
+ bool get done => _done;
+ bool _done = false;
// TODO(nweiz): make this a read-only view once issue 8321 is fixed.
@@ -73,31 +74,12 @@ class Schedule {
/// added to this list.
final errors = <ScheduleError>[];
- /// The task queue that's currently being run. One of [tasks], [onException],
- /// or [onComplete]. This starts as [tasks], and can only be `null` after the
- /// schedule is done.
- TaskQueue get currentQueue =>
- _state == ScheduleState.DONE ? null : _currentQueue;
+ /// The task queue that's currently being run, or `null` if there is no such
+ /// queue. One of [tasks], [onException], or [onComplete]. This will be `null`
+ /// before the schedule starts running.
+ TaskQueue get currentQueue => _done ? null : _currentQueue;
TaskQueue _currentQueue;
- /// The time, in milliseconds, to wait before terminating a task queue for
- /// inactivity. Defaults to 30 seconds. This can be set to `null` to disable
- /// timeouts entirely.
- ///
- /// If a task queue times out, an error will be raised that can be handled as
- /// usual in the [onException] and [onComplete] queues. If [onException] times
- /// out, that can only be handled in [onComplete]; if [onComplete] times out,
- /// that cannot be handled.
- ///
- /// If a task times out and then later completes with an error, that error
- /// cannot be handled. The user will still be notified of it.
- int get timeoutMs => _timeoutMs;
- int _timeoutMs = 30 * 1000;
- set timeoutMs(int value) {
- _timeoutMs = value;
- heartbeat();
- }
-
/// The number of out-of-band callbacks that have been registered with
/// [wrapAsync] but have yet to be called.
int _pendingCallbacks = 0;
@@ -107,17 +89,11 @@ class Schedule {
/// while [_pendingCallbacks] is non-zero.
Completer _noPendingCallbacks;
- /// The timer for keeping track of task timeouts. This may be null.
- Timer _timeoutTimer;
-
/// Creates a new schedule with empty task queues.
Schedule() {
_tasks = new TaskQueue._("tasks", this);
_onComplete = new TaskQueue._("onComplete", this);
_onException = new TaskQueue._("onException", this);
- _currentQueue = _tasks;
-
- heartbeat();
}
/// Sets up this schedule by running [setUp], then runs all the task queues in
@@ -130,7 +106,6 @@ class Schedule {
throw new ScheduleError.from(this, e, stackTrace: stackTrace);
}
- _state = ScheduleState.RUNNING;
return tasks._run();
}).catchError((e) {
errors.add(e);
@@ -154,8 +129,7 @@ class Schedule {
throw e;
});
}).whenComplete(() {
- if (_timeoutTimer != null) _timeoutTimer.cancel();
- _state = ScheduleState.DONE;
+ _done = true;
});
}
@@ -164,17 +138,18 @@ class Schedule {
///
/// The metadata in [AsyncError]s and [ScheduleError]s will be preserved.
void signalError(error, [stackTrace]) {
- heartbeat();
-
var scheduleError = new ScheduleError.from(this, error,
stackTrace: stackTrace, task: currentTask);
- if (_state == ScheduleState.DONE) {
+ if (_done) {
+ errors.add(scheduleError);
throw new StateError(
"An out-of-band error was signaled outside of wrapAsync after the "
"schedule finished running.\n"
"${errorString()}");
- } else if (state == ScheduleState.SET_UP) {
- // If we're setting up, throwing the error will pipe it into the main
+ } else if (currentQueue == null) {
+ // If we're not done but there's no current queue, that means we haven't
+ // started yet and thus we're in setUp or the synchronous body of the
+ // function. Throwing the error will thus pipe it into the main
// error-handling code.
throw scheduleError;
} else {
@@ -182,21 +157,6 @@ class Schedule {
}
}
- /// Notifies the schedule of an error that occurred in a task or out-of-band
- /// callback after the appropriate queue has timed out. If this schedule is
- /// still running, the error will be added to the errors list to be shown
- /// along with the timeout error; otherwise, a top-level error will be thrown.
- void _signalPostTimeoutError(error, [stackTrace]) {
- var scheduleError = new ScheduleError.from(this, error,
- stackTrace: stackTrace);
- errors.add(scheduleError);
- if (_state == ScheduleState.DONE) {
- throw new StateError(
- "An out-of-band error was caught after the test timed out.\n"
- "${errorString()}");
- }
- }
-
/// Returns a function wrapping [fn] that pipes any errors into the schedule
/// chain. This will also block the current task queue from completing until
/// the returned function has been called. It's used to ensure that
@@ -205,29 +165,18 @@ class Schedule {
/// The top-level `wrapAsync` function should usually be used in preference to
/// this.
Function wrapAsync(fn(arg)) {
- if (_state == ScheduleState.DONE) {
+ if (_done) {
throw new StateError("wrapAsync called after the schedule has finished "
"running.");
}
- heartbeat();
-
- var queue = currentQueue;
- // It's possible that the queue timed out before this.
- bool _timedOut() => queue != currentQueue || _pendingCallbacks == 0;
_pendingCallbacks++;
return (arg) {
try {
return fn(arg);
} catch (e, stackTrace) {
- if (_timedOut()) {
- _signalPostTimeoutError(e, stackTrace);
- } else {
- signalError(e, stackTrace);
- }
+ signalError(e, stackTrace);
} finally {
- if (_timedOut()) return;
-
_pendingCallbacks--;
if (_pendingCallbacks == 0 && _noPendingCallbacks != null) {
_noPendingCallbacks.complete();
@@ -246,38 +195,6 @@ class Schedule {
return "The schedule had ${errors.length} errors:\n$errorStrings";
}
- /// Notifies the schedule that progress is being made on an asynchronous task.
- /// This resets the timeout timer, and can be used in long-running tasks to
- /// keep them from timing out.
- void heartbeat() {
- if (_timeoutTimer != null) _timeoutTimer.cancel();
- if (_timeoutMs == null) {
- _timeoutTimer = null;
- } else {
- _timeoutTimer = new Timer(_timeoutMs, _signalTimeout);
- }
- }
-
- /// The callback to run when the timeout timer fires. Notifies the current
- /// queue that a timeout has occurred.
- void _signalTimeout(_) {
- // Reset the timer so that we can detect timeouts in the onException and
- // onComplete queues.
- _timeoutTimer = null;
-
- var error = new ScheduleError.from(this, "The schedule timed out after "
- "${_timeoutMs}ms of inactivity.", task: currentTask);
-
- _pendingCallbacks = 0;
- if (_noPendingCallbacks != null) {
- var noPendingCallbacks = _noPendingCallbacks;
- _noPendingCallbacks = null;
- noPendingCallbacks.completeError(error);
- } else {
- currentQueue._signalTimeout(error);
- }
- }
-
/// Returns a [Future] that will complete once there are no pending
/// out-of-band callbacks.
Future _awaitNoPendingCallbacks() {
@@ -287,28 +204,6 @@ class Schedule {
}
}
-/// An enum of states for a [Schedule].
-class ScheduleState {
- /// The schedule can have tasks added to its queue, but is not yet running
- /// them.
- static const SET_UP = const ScheduleState._("SET_UP");
-
- /// The schedule is actively running tasks. This includes running tasks in
- /// [Schedule.onException] and [Schedule.onComplete].
- static const RUNNING = const ScheduleState._("RUNNING");
-
- /// The schedule has finished running all its tasks, either successfully or
- /// with an error.
- static const DONE = const ScheduleState._("DONE");
-
- /// The name of the state.
- final String name;
-
- const ScheduleState._(this.name);
-
- String toString() => name;
-}
-
/// A queue of asynchronous tasks to execute in order.
class TaskQueue {
// TODO(nweiz): make this a read-only view when issue 8321 is fixed.
@@ -327,10 +222,6 @@ class TaskQueue {
/// error.
ScheduleError _error;
- /// The [SubstituteFuture] for the currently-running task in the queue, or
- /// null if no task is currently running.
- SubstituteFuture _taskFuture;
-
TaskQueue._(this.name, this._schedule);
/// Schedules a task, [fn], to run asynchronously as part of this queue. Tasks
@@ -352,16 +243,10 @@ class TaskQueue {
/// Runs all the tasks in this queue in order.
Future _run() {
_schedule._currentQueue = this;
- _schedule.heartbeat();
return Future.forEach(_contents, (task) {
_schedule._currentTask = task;
if (_error != null) throw _error;
-
- _taskFuture = new SubstituteFuture(task.fn());
- return _taskFuture.whenComplete(() {
- _taskFuture = null;
- _schedule.heartbeat();
- }).catchError((e) {
+ return task.fn().catchError((e) {
if (_error != null) _schedule.errors.add(_error);
throw new ScheduleError.from(_schedule, e, task: task);
});
@@ -369,7 +254,6 @@ class TaskQueue {
_schedule._currentTask = null;
return _schedule._awaitNoPendingCallbacks();
}).then((_) {
- _schedule.heartbeat();
if (_error != null) throw _error;
});
}
@@ -383,23 +267,6 @@ class TaskQueue {
_error = error;
}
- /// Notifies the queue that it has timed out and it needs to terminate
- /// immediately with a timeout error.
- void _signalTimeout(ScheduleError error) {
- if (_taskFuture != null) {
- // Catch errors coming off the old task future, in case it completes after
- // timing out.
- _taskFuture.substitute(new Future.immediateError(error)).catchError((e) {
- _schedule._signalPostTimeoutError(e);
- });
- } else {
- // This branch probably won't be reached, but it's conceivable that the
- // event loop might get pumped when _taskFuture is null but we haven't yet
- // called _awaitNoPendingCallbacks.
- _signalError(error);
- }
- }
-
String toString() => name;
/// Returns a detailed representation of the queue as a tree of tasks. If
« no previous file with comments | « pkg/scheduled_test/lib/scheduled_test.dart ('k') | pkg/scheduled_test/lib/src/schedule_error.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698