@@ -182,7 +182,7 @@ let processClientEvent (state: ClientState) (post: ClientEvent -> unit) msg : As
182
182
183
183
rc.Reply(())
184
184
185
- return state
185
+ return { state with ServerProcess = None }
186
186
187
187
| GetState rc ->
188
188
rc.Reply( state)
@@ -203,7 +203,7 @@ let processClientEvent (state: ClientState) (post: ClientEvent -> unit) msg : As
203
203
return { state with ServerStderrLineReadTask = nextStdErrLineReadTask }
204
204
205
205
| RpcMessageReceived result ->
206
- let readJsonRpcHeader ( stdout : Stream ) =
206
+ let tryReadJsonRpcHeader ( stdout : Stream ) =
207
207
let headerBytes = List< byte>()
208
208
209
209
let terminatorReached () =
@@ -213,45 +213,61 @@ let processClientEvent (state: ClientState) (post: ClientEvent -> unit) msg : As
213
213
&& headerBytes[ headerBytes.Count - 2 ] = ( byte '\r' )
214
214
&& headerBytes[ headerBytes.Count - 1 ] = ( byte '\n' )
215
215
216
- while not ( terminatorReached()) do
216
+ let mutable eof = false
217
+ while ( not eof && not ( terminatorReached())) do
217
218
let b : int = stdout.ReadByte()
218
219
if b < 0 then
219
- let failureMessage = ( sprintf " readJsonRpcHeader: EOF, b=%d ; bytes=%d ; \" %s \" " ( int b) ( headerBytes.Count) ( headerBytes.ToArray() |> Encoding.UTF8.GetString))
220
- failwith failureMessage
220
+ eof <- true
221
221
else
222
222
headerBytes.Add( byte b)
223
223
()
224
224
225
- let headers =
226
- Encoding.UTF8.GetString( headerBytes.ToArray())
227
- |> _. Split( " \r\n " )
228
- |> Seq.filter ( fun s -> s.Length > 0 )
229
- |> Seq.map (_. Split( " :" ))
225
+ match eof with
226
+ | true ->
227
+ None
228
+
229
+ | false ->
230
+ let headers =
231
+ Encoding.UTF8.GetString( headerBytes.ToArray())
232
+ |> _. Split( " \r\n " )
233
+ |> Seq.filter ( fun s -> s.Length > 0 )
234
+ |> Seq.map (_. Split( " :" ))
230
235
231
- let contentLength =
232
- headers
233
- |> Seq.filter ( fun a -> a[ 0 ]. ToLower() .Trim() = " content-length" )
234
- |> Seq.map ( fun a -> a[ 1 ] |> Int32.Parse)
235
- |> Seq.head
236
+ let contentLength =
237
+ headers
238
+ |> Seq.filter ( fun a -> a[ 0 ]. ToLower() .Trim() = " content-length" )
239
+ |> Seq.map ( fun a -> a[ 1 ] |> Int32.Parse)
240
+ |> Seq.head
236
241
237
- {| ContentLength = contentLength; ContentType = None |}
242
+ Some {| ContentLength = contentLength; ContentType = None |}
238
243
239
244
let readNextJsonRpcMessage () =
240
- try
241
- let stdout = state.ServerProcess.Value.StandardOutput.BaseStream
242
- if not stdout.CanRead then
243
- failwith " stdout.CanRead = false"
244
- let header = readJsonRpcHeader stdout
245
- let content : byte [] = Array.zeroCreate header.ContentLength
246
- let bytesRead = stdout.Read( content)
247
- if bytesRead <> header.ContentLength then
248
- failwith " readNextJsonRpcMessage: could not read full content"
249
-
250
- let msg = Encoding.UTF8.GetString( content) |> JObject.Parse
251
-
252
- post ( RpcMessageReceived ( Ok ( Some msg)))
253
- with ex ->
254
- post ( RpcMessageReceived ( Error ex))
245
+ match state.ServerProcess with
246
+ | None ->
247
+ logMessage " RpcMessageReceived" " no state.ServerProcess, will not read next rpc message"
248
+ ()
249
+
250
+ | Some serverProcess ->
251
+ try
252
+ let stdout = serverProcess.StandardOutput.BaseStream
253
+ if not stdout.CanRead then
254
+ failwith " stdout.CanRead = false"
255
+ let headerMaybe = tryReadJsonRpcHeader stdout
256
+ match headerMaybe with
257
+ | None ->
258
+ logMessage " RpcMessageReceived" " readNextJsonRpcMessage: EOF received when reading header"
259
+ ()
260
+ | Some header ->
261
+ let content : byte [] = Array.zeroCreate header.ContentLength
262
+ let bytesRead = stdout.Read( content)
263
+ if bytesRead <> header.ContentLength then
264
+ failwith " readNextJsonRpcMessage: could not read full content"
265
+
266
+ let msg = Encoding.UTF8.GetString( content) |> JObject.Parse
267
+
268
+ post ( RpcMessageReceived ( Ok ( Some msg)))
269
+ with ex ->
270
+ post ( RpcMessageReceived ( Error ex))
255
271
256
272
match result with
257
273
| Error e ->
@@ -365,14 +381,20 @@ let processClientEvent (state: ClientState) (post: ClientEvent -> unit) msg : As
365
381
| SendRpcMessage rpcMsg ->
366
382
let rpcMsgJson = ( string rpcMsg)
367
383
368
- let serverStdin = state.ServerProcess.Value.StandardInput
369
- let formattedMessage = String.Format( " Content-Length: {0}\r\n\r\n {1}" , rpcMsgJson.Length, rpcMsgJson)
370
- serverStdin.Write( formattedMessage)
371
- serverStdin.Flush()
384
+ match state.ServerProcess with
385
+ | None ->
386
+ logMessage " SendRpcMessage" ( sprintf " dropping rpcMsg as there is no state.ServerProcess: %s " rpcMsgJson)
387
+ return state
388
+
389
+ | Some serverProcess ->
390
+ let serverStdin = serverProcess.StandardInput
391
+ let formattedMessage = String.Format( " Content-Length: {0}\r\n\r\n {1}" , rpcMsgJson.Length, rpcMsgJson)
392
+ serverStdin.Write( formattedMessage)
393
+ serverStdin.Flush()
372
394
373
- let newRpcLog = state.RpcLog @ [{ Source = Client; TimestampMS = 0 ; Message = rpcMsg }]
395
+ let newRpcLog = state.RpcLog @ [{ Source = Client; TimestampMS = 0 ; Message = rpcMsg }]
374
396
375
- return { state with RpcLog = newRpcLog }
397
+ return { state with RpcLog = newRpcLog }
376
398
377
399
| EmitLogMessage ( timestamp, logger, msg) ->
378
400
let offsetMs = int ( timestamp - state.SetupTimestamp) .TotalMilliseconds
0 commit comments