Skip to content

Commit

Permalink
Websocket CPU efficiency improvements. (#711)
Browse files Browse the repository at this point in the history
I see high cpu usage using the `fsdocs watch` command in current
release version. It appears that the loop inside the socket is running
constantly since it never yields to receive socket messages from the
client, causing the process to use 100% of available CPU. Also, since
the reload creates a new socket connection (and suave creates a new
handler) this compounds since a new infinite loop is created after
every reload.

I've replaced the mutable boolean with a ManualResetEvent which all
connected sockets block on until a reload is called for. Once the
socket connection is closed the handler exits. I chose
ManualResetEvent over AutoResetEvent because we want all connected
sockets to restart at the same time, rather than individually, since
someone might have multiple tabs open.
  • Loading branch information
amcguier authored Oct 11, 2021
1 parent 2b6ad05 commit 816763f
Showing 1 changed file with 8 additions and 14 deletions.
22 changes: 8 additions & 14 deletions src/FSharp.Formatting.CommandTool/BuildCommand.fs
Original file line number Diff line number Diff line change
Expand Up @@ -290,21 +290,15 @@ module Serve =
tag.Replace("{{PORT}}", string port)


let mutable signalHotReload = false

let signalHotReload = new System.Threading.ManualResetEvent(false);

let socketHandler (webSocket : WebSocket) _ = socket {
while true do
signalHotReload.WaitOne() |> ignore
signalHotReload.Reset() |> ignore
let emptyResponse = [||] |> ByteSegment
//not sure what this was needed for
//do!
// refreshEvent.Publish
// |> Control.Async.AwaitEvent
// |> Suave.Sockets.SocketOp.ofAsync
//do! webSocket.send Text (ByteSegment (Encoding.UTF8.GetBytes "refreshed")) true
if signalHotReload then
printfn "Triggering hot reload on the client"
do! webSocket.send Close emptyResponse true
signalHotReload <- false
printfn "Triggering hot reload on the client"
do! webSocket.send Close emptyResponse true
}

let startWebServer outputDirectory localPort =
Expand Down Expand Up @@ -842,7 +836,7 @@ type CoreBuildOptions(watch) =
if runDocContentPhase2() then
regenerateSearchIndex()
)
Serve.signalHotReload <- true
Serve.signalHotReload.Set() |> ignore
}
|> Async.Start
)
Expand All @@ -860,7 +854,7 @@ type CoreBuildOptions(watch) =
if runGeneratePhase2() then
regenerateSearchIndex()
)
Serve.signalHotReload <- true
Serve.signalHotReload.Set() |> ignore
}
|> Async.Start
)
Expand Down

0 comments on commit 816763f

Please sign in to comment.