Skip to content
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

Make ServerProgressReport threadsafe #1130

Merged
merged 1 commit into from
Jul 9, 2023

Conversation

TheAngryByrd
Copy link
Member

@TheAngryByrd TheAngryByrd commented Jul 8, 2023

WHAT

🤖 Generated by Copilot at 2e12738

This pull request improves the cancellation and progress reporting of long-running tasks in the LSP servers. It introduces a new computation expression for AdaptiveFSharpLspServer and refactors the existing logic in FSharpLspClient to use async tasks and semaphores.

🤖 Generated by Copilot at 2e12738

We're refactoring code with a new computation
To handle cancellation and progress of our mission
We'll use async tasks and tokens and semaphores
And send our LSP messages as we sail the shores

🔄🚀🛠️

WHY

It's possible for the progress report to get out of sync with reality, it will show the progress dialogue box with no way to close it because it's possible to send Begin after End. This resolves that.

HOW

🤖 Generated by Copilot at 2e12738

  • Refactor progress reporting to use cancellableTask and locker semaphore for consistency and cancellation support (link, link, link)
  • Add AwaitableDisposable type and LockAsync extension method for SemaphoreSlim to handle async disposables safely and conveniently (link)
  • Add namespace imports for System.Threading.Tasks, System.Threading, and IcedTasks to use Task, CancellationToken, and cancellableTask types and methods (link, link)

@@ -712,8 +713,7 @@ type AdaptiveFSharpLspServer

use progressReport = new ServerProgressReport(lspClient)

progressReport.Begin($"Loading {projects.Count} Projects")
|> Async.StartImmediate
progressReport.Begin($"Loading {projects.Count} Projects") (CancellationToken.None) |> ignore<Task<unit>>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

callsite change to CancellableTask

// and https://gist.github.com/brendankowitz/5949970076952746a083054559377e56
type SemaphoreSlim with

member x.LockAsync(?ct: CancellationToken) =
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Helper so callers don't have to deal with fun try/finally semantics.

?cancellable = cancellable,
?message = message,
?percentage = percentage
cancellableTask {
Copy link
Member Author

@TheAngryByrd TheAngryByrd Jul 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Switched to CancellableTask since Async doesn't know how to Await generic Awaitables.

@TheAngryByrd TheAngryByrd force-pushed the threadsafe-progress branch from 2e12738 to 02461c5 Compare July 8, 2023 16:12
@TheAngryByrd TheAngryByrd requested a review from baronfel July 8, 2023 16:14
@TheAngryByrd TheAngryByrd force-pushed the threadsafe-progress branch from 02461c5 to dc7f0bf Compare July 8, 2023 16:54
@baronfel
Copy link
Contributor

baronfel commented Jul 9, 2023

Noice 👍 The helpers are a wonderful thing to have.

@baronfel baronfel merged commit 59b6bb1 into ionide:main Jul 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants