Skip to content

Instantly share code, notes, and snippets.

@TheAngryByrd
Last active August 29, 2015 14:21
Show Gist options
  • Save TheAngryByrd/99aea6130373662c7621 to your computer and use it in GitHub Desktop.
Save TheAngryByrd/99aea6130373662c7621 to your computer and use it in GitHub Desktop.
Rx Spawn Child Process
let tryDontCare f =
try
f()
with | _ -> ()
let observableFromProcess program args =
Observable.Create(fun (obs : IObserver<string>) ->
let pInfo = ProcessStartInfo(program,args)
pInfo.RedirectStandardOutput <- true
pInfo.RedirectStandardError <- true
pInfo.UseShellExecute <- false
let shellProcess = Process.Start(pInfo)
shellProcess.BeginOutputReadLine()
shellProcess.BeginErrorReadLine()
let exitSub = shellProcess.Exited
|> Observable.map(fun _ -> shellProcess.ExitCode)
|> Observable.filter(fun exitCode -> exitCode <> 0)
|> Observable.map(fun exitCode -> new Exception(sprintf "Process exited with %d" exitCode))
|> Observable.subscribe(obs.OnError)
let dataFeed =
shellProcess.OutputDataReceived
|> Observable.map(fun x -> x.Data)
|> Observable.subscribe(obs.OnNext)
//WARNING: Sometimes errors aren't really "errors", people just like red text for warnings
//May be better to use a discriminated union and have the subscriber determine what to do
// let errorFeed =
// shellProcess.ErrorDataReceived
// |> Observable.map (fun x -> Exception(x.Data))
// |> Observable.subscribe (obs.OnError)
Action(fun () ->
shellProcess.CancelOutputRead |> tryDontCare
dataFeed.Dispose |> tryDontCare
exitSub.Dispose |> tryDontCare
shellProcess.Kill |> tryDontCare
shellProcess.Dispose |> tryDontCare
))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment