-
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
fixing caching of cancelled cached tasks #1221
fixing caching of cancelled cached tasks #1221
Conversation
type TaskCompletionSource<'a> with | ||
/// https://github.com/dotnet/runtime/issues/47998 | ||
member tcs.TrySetFromTask(real : Task<'a>) = | ||
task { | ||
try | ||
let! r = real | ||
tcs.TrySetResult r |> ignore<bool> | ||
with | ||
| :? OperationCanceledException as x -> tcs.TrySetCanceled(x.CancellationToken) |> ignore<bool> | ||
| ex -> tcs.TrySetException ex |> ignore<bool> | ||
} | ||
|> ignore<Task<unit>> |
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 of the ContinueWith
style in the previous version
cached <- | ||
match cached with | ||
| null -> createCached () | ||
| x when x.IsCompleted && not real.IsCompleted -> |
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.
The main fix
let! ct = CancellableTask.getCancellationToken () | ||
let it = input.GetValue t | ||
use _s = ct.Register(fun () -> it.Cancel()) | ||
let! i = it |
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.
Most of this stuff is happening with the extension methods that use https://github.com/fsharp/FsAutoComplete/blob/9494bbf9554844dde4dcb740cd2839c6d507e414/src/FsAutoComplete.Core/AdaptiveExtensions.fs#L403-L408
dd5290d
to
921b5e1
Compare
Primer
The way the AsyncAdaptive is implemented using ref-counting for tasks that depend on tasks. So if a dependent task (let's say getting a type signature hint) asks for a currently running task's result (like a typecheck) but it isn't finished, we create a
TaskCompletionSource
and transfer state to it when the "real" task is finished. This allows us to have to have many dependent sources still awaiting the typecheck (like say a codefix) but allows us to cancel the hint request if the user's mouse moves away.Main problem is we were caching those cancelled tasks while the real task may still be running. Since no updates happened, Adaptive wouldn't mark the dependent tree out of date and forever getting "Task was cancelled" in places we should recompute.