Skip to content

ZelAnton/ProcessKit-fSharp

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

40 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ProcessKit

F# async child-process management for .NET: whole-tree kill-on-drop (no orphans), streaming, pipelines, timeouts, and supervision.

Status: pre-1.0, API in progress. ProcessKit is an F# port of the Rust crate ProcessKit-rs and is being built feature by feature. The public API is not yet frozen — expect additions until the 1.0 release. See CHANGELOG.md for what has landed.

Install

dotnet add package ProcessKit

Quick start

Every run returns Task<Result<_, ProcessError>> — a non-zero exit is data for the capture verbs (OutputString/OutputBytes/ExitCode/Probe) and an error only for the success-requiring verbs (Run/RunUnit).

open ProcessKit

task {
    // Require a zero exit; return stdout, trailing whitespace trimmed.
    let head = Command.create "git" |> Command.args [ "rev-parse"; "HEAD" ]

    match! head.Run() with
    | Ok sha -> printfn $"HEAD is {sha}"
    | Error err -> eprintfn $"{err.Message}"

    // Shell-free pipeline: each stage's stdout feeds the next stage's stdin, all in one
    // kill-on-dispose group. The exit status follows pipefail.
    let pipeline =
        (Command.create "cat" |> Command.arg "access.log")
            .Pipe(Command.create "grep" |> Command.arg "ERROR")
            .Pipe(Command.create "wc" |> Command.arg "-l")

    match! pipeline.Run() with
    | Ok count -> printfn $"{count} error lines"
    | Error err -> eprintfn $"{err.Message}"
}

From C# the same surface is available as fluent methods (command.Run(), command.Pipe(next).OutputString(), …).

Highlights

  • Whole-tree kill-on-drop — a process and everything it spawns is reaped on dispose (Windows Job Object KILL_ON_JOB_CLOSE; Linux/macOS POSIX process group), or on GC finalization as a safety net.
  • Honest resultsProcessError distinguishes spawn / not-found / non-zero exit / signal / timeout / cancellation; the verb you choose decides whether a non-zero exit is data or an error.
  • Streaming & interactive I/OCommand.Start() returns a live RunningProcess with StdoutLines() / OutputEvents() as IAsyncEnumerable, interactive stdin, and readiness probes (WaitForLine / WaitForPort / WaitFor).
  • Timeouts, cancellation, retryCommand.Timeout / TimeoutGrace / CancelOn / Retry, plus Command.OkCodes to accept non-zero exits as success.
  • Shell-free pipelinesCommand.Pipe with pipefail semantics and UncheckedInPipe.
  • SupervisionSupervisor keeps a command alive with restart policies, exponential backoff + jitter, and a failure-storm guard.
  • Tree control & resource limitsProcessGroup.Signal / Suspend / Resume / Members, and ProcessGroup.Create(options) with ResourceLimits (memory / process count / CPU) enforced by a Windows Job Object or a Linux cgroup v2.
  • Stats & profilingProcessGroup.Stats / SampleStats and RunningProcess.Profile (CPU / peak memory).
  • ErgonomicsCliClient (a program with shared defaults), top-level Exec.run / Exec.outputAll, and shared-group running (ProcessGroup is itself an IProcessRunner).
  • Observability — optional Command.WithLogger lifecycle events (argv/env never logged), and ProcessKit.Extensions.DependencyInjection's AddProcessKit.
  • TestableProcessKit.Testing.ScriptedRunner and RecordReplayRunner (record/replay cassettes) are subprocess-free IProcessRunners for hermetic tests.

License

MIT

About

F# async child-process management for tokio: whole-tree kill-on-drop (no orphans), plus streaming, pipelines, timeouts, and supervision library.

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors