run<T> method

  1. @override
Future<T> run<T>(
  1. ChildJob<T> child, {
  2. FutureOr<void> dispose(
    1. T value
    )?,
  3. FutureOr<void> discard(
    1. T value
    )?,
})
override

Starts child right now, as a child of this job, ahead of whatever an engine would have put it through.

Starts synchronously, then returns a future with the child's value after the child, its children and its cleanup finish; a child's error or cancellation reaches the future with its original stack trace. When the child succeeds while the parent's body is still active, the future checks the parent, for a cancellation and for the rules of its domain, and a check that throws takes the value with it. So a value the child hands over is registered on the call, with dispose or discard, and not on the line after it: that line is never reached.

final db = await ctx.run(connect, discard: (db) => db.close());

dispose and discard work as in abandonable, and passing both is an ArgumentError thrown before the child starts. Admission errors are synchronous: an ArgumentError for a handle that is not a job of this core or one an engine does not own; a StateError for a job already started or finished, and for a call made after this job's body has ended or from unattended work; and the parent's own Cancelled if the parent is already cancelled. An ArgumentError or a StateError leaves child with the code that made it: a job of Job.deferred stays unstarted.

See Running a child and When ctx.run refuses a child on the children page, and Registering on arrival on the cleanup rules page.

Implementation

@override
Future<T> run<T>(
  ChildJob<T> child, {
  FutureOr<void> Function(T value)? dispose,
  FutureOr<void> Function(T value)? discard,
}) {
  // Before the child starts: an admission error must leave nothing
  // running behind it.
  _oneCleanupOnly(dispose, discard);
  startChild(child);

  return _awaitChild(child, dispose: dispose, discard: discard);
}