Skip to content

Commit

Permalink
+ added signal handlers for shutting down child nimsuggest process in…
Browse files Browse the repository at this point in the history
… case of abnormal program termination: SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGPIPE are currently handled (#153)
  • Loading branch information
nickysn authored Jan 30, 2024
1 parent c42c0b0 commit bfb8f56
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions nimlangserver.nim
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import macros, strformat, faststreams/async_backend,
asyncprocmonitor, std/strscans, json_serialization, serialization/formats,
std/json, std/parseutils

when defined(posix):
import posix

const
RESTART_COMMAND = "nimlangserver.restart"
Expand Down Expand Up @@ -67,6 +69,7 @@ type
workspaceConfiguration: Future[JsonNode]
filesWithDiags: HashSet[string]
lastNimsuggest: Future[Nimsuggest]
childNimsuggestProcessesStopped*: bool
isShutdown*: bool
storageDir*: string
cmdLineClientProcessId: Option[int]
Expand Down Expand Up @@ -192,9 +195,17 @@ proc getCharacter(ls: LanguageServer, uri: string, line: int, character: int): i
return ls.openFiles[uri].fingerTable[line].utf16to8(character)

proc stopNimsuggestProcesses(ls: LanguageServer) {.async.} =
for ns in ls.projectFiles.values:
let ns = await ns
ns.stop()
if not ls.childNimsuggestProcessesStopped:
debug "stopping child nimsuggest processes"
ls.childNimsuggestProcessesStopped = true
for ns in ls.projectFiles.values:
let ns = await ns
ns.stop()
else:
debug "child nimsuggest processes already stopped: CHECK!"

proc stopNimsuggestProcessesP(ls: ptr LanguageServer) =
waitFor stopNimsuggestProcesses(ls[])

proc initialize(p: tuple[ls: LanguageServer, pipeInput: AsyncInputStream], params: InitializeParams):
Future[InitializeResult] {.async.} =
Expand Down Expand Up @@ -1178,6 +1189,11 @@ proc ensureStorageDir*: string =
result = getTempDir() / "nimlangserver"
discard existsOrCreateDir(result)

var
# global var, only used in the signal handlers (for stopping the child nimsuggest
# processes during an abnormal program termination)
globalLS: ptr LanguageServer

when isMainModule:

proc getVersionFromNimble(): string =
Expand Down Expand Up @@ -1218,8 +1234,11 @@ when isMainModule:
let
connection = StreamConnection.new(Async(fileOutput(stdout, allowAsyncOps = true)))
pipeInput = asyncPipeInput(pipe)
var
ls = registerHandlers(connection, pipeInput, storageDir, cmdLineParams)

globalLS = addr ls

if cmdLineParams.clientProcessId.isSome:
debug "Registering monitor for process id, specified on command line", clientProcessId=cmdLineParams.clientProcessId.get

Expand All @@ -1235,6 +1254,11 @@ when isMainModule:

hookAsyncProcMonitor(cmdLineParams.clientProcessId.get, onCmdLineClientProcessExit)

when defined(posix):
onSignal(SIGINT, SIGTERM, SIGHUP, SIGQUIT, SIGPIPE):
debug "Terminated via signal", sig
globalLS.stopNimsuggestProcessesP()

waitFor connection.start(pipeInput)
debug "exiting main thread", isShutdown=ls.isShutdown
quit(if ls.isShutdown: 0 else: 1)
Expand Down

0 comments on commit bfb8f56

Please sign in to comment.