@@ -12,7 +12,9 @@ import osproc,
12
12
chronicles,
13
13
protocol/ types,
14
14
std/ options,
15
- chronos
15
+ chronos,
16
+ chronos/ asyncproc ,
17
+ stew/ [byteutils]
16
18
17
19
const REQUEST_TIMEOUT* = 120000
18
20
const HighestSupportedNimSuggestProtocolVersion = 4
78
80
openFiles* : OrderedSet[string ]
79
81
successfullCall* : bool
80
82
errorCallback: NimsuggestCallback
81
- process* : Process
83
+ process* : AsyncProcessRef
82
84
port* : int
83
85
root: string
84
86
requestQueue: Deque[SuggestCall]
@@ -224,30 +226,11 @@ proc markFailed(self: Nimsuggest, errMessage: string) {.raises: [].} =
224
226
if self.errorCallback != nil :
225
227
self.errorCallback(self)
226
228
227
- proc readPort(param: tuple [ns: ptr NimSuggestImpl, process: Process]) {.thread.} =
228
- try :
229
- var line = param.process.outputStream.readLine & " \n "
230
- param.ns.port = line.strip.parseInt
231
- except CatchableError:
232
- error " Failed to read nimsuggest port"
233
- var msg = failedToken & " \n "
234
- param.ns.port = - 1
235
-
236
- proc logStderr(param: tuple [root: string , process: Process]) {.thread.} =
237
- try :
238
- var line = param.process.errorStream.readLine
239
- while line != " \0 " :
240
- stderr.writeLine & " ******NIM SUGGEST ERRROR***** { param.root} \n "
241
- stderr.writeLine fmt " >> {line}"
242
- line = param.process.errorStream.readLine
243
- except IOError:
244
- discard
245
-
246
229
proc stop* (self: Nimsuggest) =
247
230
debug " Stopping nimsuggest for " , root = self.root
248
231
try :
249
- self.process.kill()
250
- self.process.close()
232
+ let res = self.process.kill()
233
+ debug " Stopped nimsuggest " , res = res
251
234
except Exception as ex:
252
235
writeStackTrace(ex)
253
236
@@ -306,14 +289,10 @@ proc getNimsuggestCapabilities*(nimsuggestPath: string):
306
289
if cap.isSome:
307
290
result .incl(cap.get)
308
291
309
- proc waitUntilPortIsRead(ns: NimSuggest): Future[void ] {.async.} =
310
- while ns.port == 0 :
311
- await sleepAsync(10 )
312
-
313
- if ns.port == - 1 :
314
- ns.markFailed " Failed to start nimsuggest"
315
- else :
316
- debug " Started nimsuggest" , port = ns.port, root = ns.root
292
+ proc logNsError(ns: NimSuggest) {.async.} =
293
+ let err = string .fromBytes(ns.process.stderrStream.read().await)
294
+ error " NimSuggest Error (stderr)" , err = err
295
+ ns.markFailed(err)
317
296
318
297
proc createNimsuggest* (root: string ,
319
298
nimsuggestPath: string ,
@@ -324,13 +303,6 @@ proc createNimsuggest*(root: string,
324
303
workingDir = getCurrentDir(),
325
304
enableLog: bool = false ,
326
305
enableExceptionInlayHints: bool = false ): Future[Nimsuggest] {.async, gcsafe.} =
327
- var
328
- thread: Thread[tuple [ns: ptr NimSuggestImpl, process: Process]]
329
- stderrThread: Thread[tuple [root: string , process: Process]]
330
-
331
- info " Starting nimsuggest" , root = root, timeout = timeout, path = nimsuggestPath,
332
- workingDir = workingDir
333
-
334
306
result = Nimsuggest()
335
307
result .requestQueue = Deque[SuggestCall]()
336
308
result .root = root
@@ -340,11 +312,14 @@ proc createNimsuggest*(root: string,
340
312
result .nimSuggestPath = nimsuggestPath
341
313
result .version = version
342
314
315
+ info "Starting nimsuggest", root = root, timeout = timeout, path = nimsuggestPath,
316
+ workingDir = workingDir
317
+
343
318
if nimsuggestPath != "":
344
319
result .protocolVersion = detectNimsuggestVersion(root, nimsuggestPath, workingDir)
345
320
if result .protocolVersion > HighestSupportedNimSuggestProtocolVersion:
346
321
result .protocolVersion = HighestSupportedNimSuggestProtocolVersion
347
- var
322
+ var
348
323
args = @[root, "--v" & $result .protocolVersion, "--autobind " ]
349
324
if result .protocolVersion >= 4 :
350
325
args.add(" --clientProcessId:" & $ getCurrentProcessId())
@@ -357,18 +332,13 @@ proc createNimsuggest*(root: string,
357
332
args.add(" --exceptionInlayHints:on" )
358
333
else :
359
334
args.add(" --exceptionInlayHints:off" )
360
- result .process = startProcess(command = nimsuggestPath,
361
- workingDir = workingDir,
362
- args = args,
363
- options = {poUsePath})
364
- # TODO better use startProcess from chronos so we dont need to spawn a thread
365
- # all this is needed to avoid the need to block on the main thread.
366
- createThread(thread, readPort, (ns: cast [ptr NimSuggestImpl](result ), process: result .process))
367
-
368
- # copy stderr of log
369
- createThread(stderrThread, logStderr, (root: root, process: result .process))
370
- await waitUntilPortIsRead(result )
371
-
335
+ result .process =
336
+ await startProcess(nimsuggestPath, arguments = args, options = { UsePath },
337
+ stdoutHandle = AsyncProcess.Pipe,
338
+ stderrHandle = AsyncProcess.Pipe)
339
+
340
+ asyncSpawn logNsError(result )
341
+ result .port = (await result .process.stdoutStream.readLine(sep= " \n " )).parseInt
372
342
else :
373
343
error " Unable to start nimsuggest. Unable to find binary on the $PATH" , nimsuggestPath = nimsuggestPath
374
344
result .markFailed fmt " Unable to start nimsuggest. `{nimsuggestPath}` is not present on the PATH"
0 commit comments