Skip to content

Commit f671d45

Browse files
committed
fix: daemon cache
ensure we can reuse an already found daemon version from another folder
1 parent 319f84e commit f671d45

1 file changed

Lines changed: 44 additions & 39 deletions

File tree

src/FSharpLint.Client/LSPFSharpLintService.fs

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,35 @@ type Msg =
2929
| Reset of AsyncReplyChannel<unit>
3030

3131
let private createAgent (ct: CancellationToken) =
32+
let tryGetVersionFromCache state version folder (replyChannel: AsyncReplyChannel<Result<JsonRpc, GetDaemonError>>) =
33+
let daemon = Map.tryFind version state.Daemons
34+
35+
match daemon with
36+
| Some daemon ->
37+
// We have a daemon for the required version in the cache, check if we can still use it.
38+
if daemon.Process.HasExited then
39+
// weird situation where the process has crashed.
40+
// Trying to reboot
41+
(daemon :> IDisposable).Dispose()
42+
43+
let newDaemonResult = createFor daemon.StartInfo
44+
45+
match newDaemonResult with
46+
| Ok newDaemon ->
47+
replyChannel.Reply(Ok newDaemon.RpcClient)
48+
49+
Some { FolderToVersion = Map.add folder version state.FolderToVersion
50+
Daemons = Map.add version newDaemon state.Daemons }
51+
| Error pse ->
52+
replyChannel.Reply(Error(GetDaemonError.FSharpLintProcessStart pse))
53+
Some state
54+
else
55+
// return running client
56+
replyChannel.Reply(Ok daemon.RpcClient)
57+
58+
Some { state with FolderToVersion = Map.add folder version state.FolderToVersion }
59+
| None -> None
60+
3261
MailboxProcessor.Start(
3362
(fun inbox ->
3463
let rec messageLoop (state: ServiceState) =
@@ -41,62 +70,38 @@ let private createAgent (ct: CancellationToken) =
4170
// get the version for that folder
4271
// look in the cache first
4372
let versionFromCache = Map.tryFind folder state.FolderToVersion
44-
4573
match versionFromCache with
4674
| Some version ->
47-
let daemon = Map.tryFind version state.Daemons
48-
49-
match daemon with
50-
| Some daemon ->
51-
// We have a daemon for the required version in the cache, check if we can still use it.
52-
if daemon.Process.HasExited then
53-
// weird situation where the process has crashed.
54-
// Trying to reboot
55-
(daemon :> IDisposable).Dispose()
56-
57-
let newDaemonResult = createFor daemon.StartInfo
58-
59-
match newDaemonResult with
60-
| Ok newDaemon ->
61-
replyChannel.Reply(Ok newDaemon.RpcClient)
62-
63-
{ FolderToVersion = Map.add folder version state.FolderToVersion
64-
Daemons = Map.add version newDaemon state.Daemons }
65-
| Error pse ->
66-
replyChannel.Reply(Error(GetDaemonError.FSharpLintProcessStart pse))
67-
state
68-
else
69-
// return running client
70-
replyChannel.Reply(Ok daemon.RpcClient)
71-
72-
{ state with
73-
FolderToVersion = Map.add folder version state.FolderToVersion }
74-
| None ->
75+
tryGetVersionFromCache state version folder replyChannel
76+
|> Option.defaultWith(fun () ->
7577
// This is a strange situation, we know what version is linked to that folder but there is no daemon
7678
// The moment a version is added, is also the moment a daemon is re-used or created
7779
replyChannel.Reply(
7880
Error(GetDaemonError.CompatibleVersionIsKnownButNoDaemonIsRunning version)
7981
)
8082

81-
state
83+
state)
8284
| None ->
8385
// Try and find a version of fsharplint daemon for our current folder
8486
let fsharpLintToolResult: Result<FSharpLintToolFound, FSharpLintToolError> =
8587
findFSharpLintTool folder
8688

8789
match fsharpLintToolResult with
8890
| Ok(FSharpLintToolFound(version, startInfo)) ->
89-
let createDaemonResult = createFor startInfo
91+
tryGetVersionFromCache state version folder replyChannel
92+
|> Option.defaultWith(fun () ->
93+
let createDaemonResult = createFor startInfo
9094

91-
match createDaemonResult with
92-
| Ok daemon ->
93-
replyChannel.Reply(Ok daemon.RpcClient)
95+
match createDaemonResult with
96+
| Ok daemon ->
97+
replyChannel.Reply(Ok daemon.RpcClient)
9498

95-
{ Daemons = Map.add version daemon state.Daemons
96-
FolderToVersion = Map.add folder version state.FolderToVersion }
97-
| Error pse ->
98-
replyChannel.Reply(Error(GetDaemonError.FSharpLintProcessStart pse))
99-
state
99+
{ Daemons = Map.add version daemon state.Daemons
100+
FolderToVersion = Map.add folder version state.FolderToVersion }
101+
| Error pse ->
102+
replyChannel.Reply(Error(GetDaemonError.FSharpLintProcessStart pse))
103+
state
104+
)
100105
| Error FSharpLintToolError.NoCompatibleVersionFound ->
101106
replyChannel.Reply(Error GetDaemonError.InCompatibleVersionFound)
102107
state

0 commit comments

Comments
 (0)