Gitility.Runtime (Gitility v0.2.0)

Copy Markdown View Source

An explicit, supervisable query runtime: one bounded native worker pool.

Every expensive Gitility operation executes as a job on a runtime's Rust-owned worker threads — never on BEAM schedulers. A shared default runtime starts lazily with conservative defaults, so small callers need zero configuration:

  • workers: max(System.schedulers_online() div 2, 1)
  • max_queue: 1_000
  • max_jobs_per_owner: 16
  • shutdown_join_timeout_ms: 5_000

The generated child spec gives shutdown shutdown_join_timeout_ms + 2_000 milliseconds. That margin lets the bounded native worker-join phase finish before a supervisor is allowed to kill the GenServer running terminate/2. Unnamed runtimes receive unique child IDs, so more than one can be placed in the same supervision tree without an explicit :name.

Gitility's library supervisor permits 10 restarts in 60 seconds. This gives its leaf runtime room to recover from a short crash burst; a persistently crashing runtime still stops the application according to normal OTP restart-intensity semantics.

Tuning means starting a named runtime in your own supervision tree — the Finch/NimblePool convention, and the only shape that lets two subsystems with different latency profiles stop sharing a queue:

children = [
  {Gitility.Runtime,
   name: MyApp.GitRuntime,
   workers: 8,
   max_queue: 500,
   max_jobs_per_owner: 16}
]

Every root store (Gitility.Repository.open/2, the provider configured by Gitility.ODB.start_link/1 and retrieved with Gitility.ODB.handle/1, or Gitility.ODB.from_objects/2) accepts runtime: and defaults to the shared instance. Snapshots and jobs inherit the runtime of the store they came from; stores composed together must share one runtime, enforced at composition time with :runtime_mismatch.

Backpressure

Queue admission can refuse with {:error, %Gitility.Error{code: :busy}} carrying retry_after_ms in details. Per-owner ceilings keep one process from monopolizing a runtime; internal parallelism (search, diff) stays within a job's assigned permit count. Asynchronous functions surface :busy immediately. Synchronous query wrappers wait retry_after_ms and retry admission once before returning :busy.

Summary

Types

t()

A runtime identifier: a registered name or pid.

Functions

The shared default runtime, started lazily on first use.

Starts a runtime instance. See the moduledoc for options.

Returns a runtime's current native admission and lifecycle counters.

Types

t()

@type t() :: atom() | pid()

A runtime identifier: a registered name or pid.

Functions

default()

@spec default() :: t() | {:error, Gitility.Error.t()}

The shared default runtime, started lazily on first use.

start_link(opts \\ [])

@spec start_link([option()]) :: {:ok, pid()} | {:error, term()}

Starts a runtime instance. See the moduledoc for options.

stats(runtime \\ :default)

@spec stats(t() | :default) :: map() | {:error, Gitility.Error.t()}

Returns a runtime's current native admission and lifecycle counters.