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

Reload projects after delay of being marked out of date #1079

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 28 additions & 17 deletions src/FsAutoComplete/LspServers/AdaptiveFSharpLspServer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@ open Ionide.LanguageServerProtocol.Types.LspResult
open Ionide.LanguageServerProtocol.Types
open Newtonsoft.Json.Linq
open Ionide.ProjInfo.ProjectSystem
open System.Reactive
open System.Reactive.Linq

open FSharp.Control.Reactive
open FsToolkit.ErrorHandling
open FsOpenTelemetry
open FsAutoComplete.Utils.Tracing
Expand Down Expand Up @@ -129,6 +132,17 @@ module AVal =
result }
:> aval<_>

/// <summary>
/// Creates observables from adaptive values
/// </summary>
module Observable =
/// <summary>
/// Creates an observable with the given object that will be executed whenever the object gets marked out-of-date. Note that it does not trigger when the object is currently out-of-date.
/// </summary>
/// <param name="aval">The aval to get out-of-date information from.</param>
/// <returns>An observable</returns>
let onWeakMarking (aval: #aval<_>) =
Observable.Create(fun (obs: IObserver<unit>) -> aval.AddWeakMarkingCallback(obs.OnNext))

module ASet =
/// Creates an amap with the keys from the set and the values given by mapping and
Expand Down Expand Up @@ -180,7 +194,7 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar

let thisType = typeof<AdaptiveFSharpLspServer>

let disposables = new System.Reactive.Disposables.CompositeDisposable()
let disposables = new Disposables.CompositeDisposable()

let rootPath = cval<string option> None

Expand Down Expand Up @@ -811,8 +825,21 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
return options |> List.map fst
}

/// <summary>
/// Evaluates the adaptive value <see cref='F:loadedProjectOptions '/> and returns its current value.
/// This should not be used inside the adaptive evaluation of other AdaptiveObjects since it does not track dependencies.
/// </summary>
/// <returns>A list of FSharpProjectOptions</returns>
let forceLoadProjects () = loadedProjectOptions |> AVal.force

do
// Reload Projects with some debouncing if `loadedProjectOptions` is out of date.
AVal.Observable.onWeakMarking loadedProjectOptions
|> Observable.throttleOn Concurrency.NewThreadScheduler.Default (TimeSpan.FromMilliseconds(200.))
|> Observable.observeOn Concurrency.NewThreadScheduler.Default
|> Observable.subscribe (forceLoadProjects >> ignore)
|> disposables.Add


let sourceFileToProjectOptions =
aval {
Expand Down Expand Up @@ -1242,7 +1269,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
/// Bypass Adaptive checking and tell the checker to check a file
let bypassAdaptiveTypeCheck (filePath: string<LocalPath>) opts =
async {

try
logger.info (
Log.setMessage "Forced Check : {file}"
Expand Down Expand Up @@ -2085,9 +2111,7 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar

try
logger.info (Log.setMessage "Initialized request {p}" >> Log.addContextDestructured "p" p)
// Starts getting project options to cache
forceLoadProjects () |> ignore

return ()
with e ->

Expand Down Expand Up @@ -4097,8 +4121,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> HashSet.single
|> WorkspaceChosen.Projs)

forceLoadProjects () |> ignore

return! Helpers.notImplemented
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down Expand Up @@ -4193,7 +4215,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore // mapping unit option to unit

forceLoadProjects () |> ignore
return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down Expand Up @@ -4223,7 +4244,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore

forceLoadProjects () |> ignore
return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down Expand Up @@ -4253,7 +4273,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore

forceLoadProjects () |> ignore
return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down Expand Up @@ -4451,7 +4470,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore

forceLoadProjects () |> ignore
return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down Expand Up @@ -4482,7 +4500,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore

forceLoadProjects () |> ignore
return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down Expand Up @@ -4513,7 +4530,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore

forceLoadProjects () |> ignore
return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down Expand Up @@ -4543,7 +4559,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore

forceLoadProjects () |> ignore
return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down Expand Up @@ -4573,7 +4588,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore

forceLoadProjects () |> ignore
return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down Expand Up @@ -4604,7 +4618,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore

forceLoadProjects () |> ignore
return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down Expand Up @@ -4636,7 +4649,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore

forceLoadProjects () |> ignore
let fileUri = Path.FilePathToUri fullPath
diagnosticCollections.ClearFor fileUri

Expand Down Expand Up @@ -4669,7 +4681,6 @@ type AdaptiveFSharpLspServer(workspaceLoader: IWorkspaceLoader, lspClient: FShar
|> AsyncResult.ofCoreResponse
|> AsyncResult.map ignore

forceLoadProjects () |> ignore
return None
with e ->
trace.SetStatusErrorSafe(e.Message).RecordExceptions(e) |> ignore
Expand Down