Skip to content
This repository has been archived by the owner on Oct 17, 2024. It is now read-only.

Commit

Permalink
Change the default propagateCancel argument (#213)
Browse files Browse the repository at this point in the history
Closes #212

Authors are more likely to expect propagation, and not cancelling is
often a hidden inefficiency which may go unnoticed and untested.

Update the doc comment to focus on the 3 ways an operation can end - as
a value, an error, or a cancellation. This will hopefully make it more
clear that the `onCancel` callback does not relate to the cancellation
of the returned operation.
  • Loading branch information
natebosch authored Mar 28, 2022
1 parent b18c73e commit 3f58c32
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 22 deletions.
12 changes: 7 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
## 2.9.0-dev

* **Potentially Breaking** The default `propagateCancel` argument to
`CancelableOperation.then` changed from `false` to `true`. In most usages this
won't have a meaningful difference in behavior, but in usages where the
behavior is important propagation is the more common need. If there are any
`CancelableOperation` with multiple listeners where canceling subsequent
computation using `.then` shouldn't also cancel the original operation, pass
`propagateCancel: false`.
* Add `StreamExtensions.firstOrNull`.

* Add a `CancelableOperation.fromSubscription()` static factory.

* Add a `CancelableOperation.race()` static method.

* Update `StreamGroup` methods that return a `Future<dynamic>` today to return
a `Future<void>` instead.

* Deprecated `AsyncCache.fetchStream`.

* Make `AsyncCache.ephemeral` invalidate itself immediately when the returned
future completes, rather than wait for a later timer event.

Expand Down
41 changes: 24 additions & 17 deletions lib/src/cancelable_operation.dart
Original file line number Diff line number Diff line change
Expand Up @@ -130,26 +130,33 @@ class CancelableOperation<T> {
return completer.future;
}

/// Creates a new cancelable operation to be completed
/// when this operation completes or is cancelled.
///
/// The [onValue] and [onError] callbacks behave in the same way as
/// for [Future.then], and the result of those callbacks is used to complete
/// the returned cancelable operation.
///
/// If [onCancel] is provided, and the this operation is canceled,
/// the [onCancel] callback is called and the returned operation completes
/// with the result returned by that call.
///
/// If [onCancel] is not provided, and this operation is canceled, then the
/// returned operation is also canceled.
///
/// If [propagateCancel] is `true` and the returned operation is canceled
/// then this operation is canceled. The default is `false`.
/// Creates a new cancelable operation to be completed when this operation
/// completes normally or as an error, or is cancelled.
///
/// If this operation completes normally the [value] is passed to [onValue]
/// and the returned operation is completed with the result.
///
/// If this operation completes as an error, and no [onError] callback is
/// provided, the returned operation is completed with the same error and
/// stack trace.
/// If this operation completes as an error, and an [onError] callback is
/// provided, the returned operation is completed with the result.
///
/// If this operation is canceled, and no [onCancel] callback is provided,
/// the returned operation is canceled.
/// If this operation is canceled, and an [onCancel] callback is provided,
/// the returned operation is completed with the result.
///
/// If the returned operation is canceled before this operation completes or
/// is canceled, the [onValue], [onError], and [onCancel] callbacks will not
/// be invoked. If [propagateCancel] is `true` (the default) then this
/// operation is canceled as well. Pass `false` if there are multiple
/// listeners on this operation and canceling the [onValue], [onError], and
/// [onCancel] callbacks should not cancel the other listeners.
CancelableOperation<R> then<R>(FutureOr<R> Function(T) onValue,
{FutureOr<R> Function(Object, StackTrace)? onError,
FutureOr<R> Function()? onCancel,
bool propagateCancel = false}) {
bool propagateCancel = true}) {
final completer =
CancelableCompleter<R>(onCancel: propagateCancel ? cancel : null);

Expand Down

0 comments on commit 3f58c32

Please sign in to comment.