-
Notifications
You must be signed in to change notification settings - Fork 156
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix cancellation crash in adaptive #1184
Fix cancellation crash in adaptive #1184
Conversation
cache.Value.New() } | ||
:> asyncaval<_> | ||
|
||
map (fun a ct -> Async.StartImmediateAsTask(mapping a, ct)) input |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactoring
@@ -628,17 +626,14 @@ module AsyncAVal = | |||
|
|||
let! ct = CancellableTask.getCancellationToken () | |||
|
|||
let s = | |||
use _s = |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactoring to use
return inner | ||
finally | ||
s.Dispose() | ||
use _s = ct.Register(fun () -> it.Cancel()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactoring to use
s2.Dispose() | ||
finally | ||
s.Dispose() | ||
use _s = ct.Register(fun () -> innerCellTask.Cancel()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactoring to use
@@ -480,43 +497,53 @@ module AsyncAVal = | |||
let ofTask (value: Task<'a>) = ConstantVal(value) :> asyncaval<_> | |||
|
|||
let ofCancellableTask (value: CancellableTask<'a>) = | |||
let mutable cache: Option<AdaptiveCancellableTask<'a>> = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Help cut down on re-evaluations.
@@ -369,7 +386,7 @@ and AdaptiveCancellableTask<'a>(cancel: unit -> unit, real: Task<'a>) = | |||
/// <summary>Will run the cancel function passed into the constructor and set the output Task to cancelled state.</summary> | |||
member x.Cancel() = | |||
cancel () | |||
cts.Cancel() | |||
cts.TryCancel() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't care if the cancellation can't be cancelled anymore. Alternative approaches would be to swap the cancel function out upon finishing of a task but this seemed easier.
a32b6e9
to
18f6f58
Compare
WHAT
🤖 Generated by Copilot at a32b6e9
This pull request enhances the
AdaptiveExtensions
module with a new type, better cancellation and disposal logic, caching, and simplification. These changes aim to improve the performance and reliability of async adaptive values, which are used for incremental and reactive computations.🤖 Generated by Copilot at a32b6e9
🛠️🚀🧹
WHY
Got this last week:
HOW
🤖 Generated by Copilot at a32b6e9
TryCancel
andTryDispose
extension methods forCancellationTokenSource
to ignoreObjectDisposedException
(link)TryCancel
andTryDispose
methods instead ofCancel
andDispose
forCancellationTokenSource
instances inRefCountingTaskCreator
andAMap
types (link, link)ofCancellableTask
andofAsync
functions inAsyncAVal
module to reuse adaptive cancellable tasks if input value has not changed (link)mapAsync
function inAsyncAVal
module by reusingmap
function with a different mapping function (link)CancellationTokenRegistration
withuse
keyword inmap
,map2
,bind
, and inner computation ofbind
functions inAsyncAVal
module (link, link, link, link)AMapAsync
module (link)