Skip to main content

AppConfig

Struct AppConfig 

Source
pub struct AppConfig {
Show 40 fields pub name: String, pub script: String, pub args: Vec<String>, pub cwd: Option<String>, pub interpreter: Option<String>, pub env: BTreeMap<String, String>, pub instances: u32, pub autorestart: bool, pub autostart: bool, pub stop_exit_codes: Vec<i32>, pub min_uptime: UpDuration, pub max_restarts: u32, pub restart_delay: Option<UpDuration>, pub exp_backoff_restart_delay: Option<UpDuration>, pub kill_signal: Option<String>, pub kill_timeout: UpDuration, pub shutdown_with_message: bool, pub listen_timeout: UpDuration, pub graceful_timeout: UpDuration, pub action_timeout: UpDuration, pub max_memory: Option<MemSize>, pub watch: bool, pub ignore_watch: Vec<String>, pub watch_delay: Option<UpDuration>, pub cron_restart: Option<String>, pub fold: Option<String>, pub user: Option<String>, pub group: Option<String>, pub out_file: Option<String>, pub err_file: Option<String>, pub merge_logs: bool, pub channel: bool, pub stdin: bool, pub wait_ready: bool, pub reuse_port: bool, pub readiness_probe: Option<ProbeConfig>, pub liveness_probe: Option<ProbeConfig>, pub watch_options: Vec<String>, pub cron_timezone: Option<String>, pub increment_var: Option<String>,
}
Expand description

Per-app configuration — one sheep’s entry in a Flockfile

Field names are the Flockfile contract (sheep-native; pm2 spellings are rejected — the importer translates them). Unknown fields are errors so typos fail loudly at parse time.

§Example

use shep_core::config::AppConfig;

let app: AppConfig = toml::from_str("name = \"web\"\nscript = \"./srv\"").unwrap();
assert!(app.autorestart); // spec default

Fields§

§name: String

Unique sheep name (required)

§script: String

Executable or script path (required)

§args: Vec<String>

Arguments passed to the script

§cwd: Option<String>

Working directory (default: daemon’s cwd at spawn registration)

§interpreter: Option<String>

Interpreter override ("none" = run script directly)

§env: BTreeMap<String, String>

Environment for the sheep (merged over the daemon’s filtered env)

§instances: u32

Instance count (“cluster” = N fork instances; spec §4)

§autorestart: bool

Restart on unexpected exit

§autostart: bool

Start when the daemon starts / on shep muster

§stop_exit_codes: Vec<i32>

Exit codes treated as clean stop (no restart)

§min_uptime: UpDuration

Uptime below this marks an exit as unstable

§max_restarts: u32

Consecutive unstable exits before errored

§restart_delay: Option<UpDuration>

Fixed delay before every restart (alternative to backoff)

§exp_backoff_restart_delay: Option<UpDuration>

Initial backoff delay; grows ×1.5 capped at 15s (spec §4)

§kill_signal: Option<String>

Stop signal, one of SIGTERM/SIGINT/SIGQUIT/SIGUSR2 (the SIG prefix and the case are both optional). Unset means SIGTERM.

A String rather than a KillSignal so the Flockfile schema and this struct’s wire form stay plain text; normalize is what refuses a name outside that set, the same split cron_restart and the watch globs already use.

§kill_timeout: UpDuration

Grace period between stop signal and SIGKILL

§shutdown_with_message: bool

Send {"kind":"shutdown"} on the shepherd channel instead of a signal

§listen_timeout: UpDuration

Readiness fallback window when no ready signal/probe configured

§graceful_timeout: UpDuration

Drain window for the old instance during reload

§action_timeout: UpDuration

How long a triggered action gets to answer on the shepherd channel before its row becomes ActionOutcome::TimedOut.

Defaults to 3s — comfortably under the 5s an RPC caller gets when it sends no deadline of its own (shep-client’s DEFAULT_DEADLINE, mirrored daemon-side as rpc’s DEFAULT_DEADLINE_MS). The margin matters more than the number: push this past that budget and a caller using the plain default gives up with DeadlineExceeded before the daemon’s own honest TimedOut row ever reaches it. A legitimately slow action (a cache flush, say) can still ask for longer, but its caller has to ask for a longer deadline in step — Client::request_with_deadline, the way shep logs -f already asks for LOG_PLANE_DEADLINE rather than the client’s default. normalize refuses a value no caller could ever satisfy, however long a deadline it asks for; a value merely above the default budget is a caller’s choice to widen its own deadline, not a config error this crate can see.

§max_memory: Option<MemSize>

Memory ceiling — polling enforcer restarts above this

§watch: bool

Watch files and restart on change

§ignore_watch: Vec<String>

Watch ignore globs (defaults added daemon-side: dot-entries, node_modules)

§watch_delay: Option<UpDuration>

Watch debounce window (default 500ms, applied daemon-side)

§cron_restart: Option<String>

Cron pattern for scheduled restarts (croner dialect)

§fold: Option<String>

Fold (group) this sheep belongs to

§user: Option<String>

Run as this user (unix)

§group: Option<String>

Run as this group (unix)

§out_file: Option<String>

Stdout log file (default: $SHEP_HOME/logs/<name>-<instance>-out.log; merge_logs collapses to <name>-out.log)

§err_file: Option<String>

Stderr log file (default: $SHEP_HOME/logs/<name>-<instance>-err.log; merge_logs collapses to <name>-err.log)

§merge_logs: bool

Merge instance logs into one file pair

§channel: bool

Open the shepherd channel on fd 3 for this app on its own, without needing wait_ready or shutdown_with_message to imply it.

Defaults to false: a socketpair plus two pump tasks per sheep is real cost weighed against spec §14.11’s single-digit-MB idle-RSS goal, so a channel is opened only when something asks for one.

§stdin: bool

Open a pipe on this sheep’s stdin, so shep whisper can write to it.

Defaults to false, and the default is the decision rather than a convenience. Without it a sheep gets /dev/null on fd 0, which is what every sheep has had until now, and three things argue for keeping it that way unless an app asks otherwise:

  • Flipping it for the whole flock is a behaviour change to processes nobody asked to change.
  • Programs detect stdin. A closed or null fd 0 is how a great many programs decide they are non-interactive — no prompt, no pager, no readline, no colour. Handing them a pipe silently moves them to the other branch.
  • It costs a descriptor and a pump task per sheep for the whole life of the process, against spec §14.11’s single-digit-MB idle-RSS goal — the same budget Self::channel’s own default is protecting.

Unlike channel, nothing implies this: wait_ready and shutdown_with_message both need fd 3 and so turn channel on for you, while nothing in shep needs a sheep’s stdin except an operator typing shep whisper. A sheep without it answers a no_stdin row and names this field.

The pipe’s write end lives as long as the sheep does, so the app sees EOF on stdin when the process is on its way out, never before.

§wait_ready: bool

Expect {"kind":"ready"} on the shepherd channel

§reuse_port: bool

Asserts that the app itself sets SO_REUSEPORT before it binds — shep binds nothing, so it cannot set the option on the app’s behalf. The child process owns the mechanism (Node ≥22’s reusePort, Go’s net.ListenConfig.Control, nginx’s reuseport); shep’s contribution is permission for the old and new instance to overlap during reload, not the socket option itself.

This field is inert today. shep never reads it: reload overlap already happens unconditionally, so setting it changes nothing and leaving it unset costs nothing. It is kept because shep import writes it for a cluster-mode pm2 app and shep flock displays it, so dropping it would silently discard a value out of an imported config. It becomes load-bearing the day shep gains a reload mode that does NOT overlap by default, which is when the permission it describes stops being free — see docs/specs/deferred.md.

§readiness_probe: Option<ProbeConfig>

Readiness probe — gates reload’s AwaitReady (spec §7)

§liveness_probe: Option<ProbeConfig>

Liveness probe — failures feed the restart policy (spec §7)

§watch_options: Vec<String>

Watch include globs (empty = watch cwd)

§cron_timezone: Option<String>

Timezone for cron_restart (IANA name)

§increment_var: Option<String>

Env var receiving the instance slot (default SHEP_INSTANCE)

Implementations§

Source§

impl AppConfig

Source

pub fn minimal(name: &str, script: &str) -> Self

A minimal config with spec defaults — the programmatic entry point

Trait Implementations§

Source§

impl Clone for AppConfig

Source§

fn clone(&self) -> AppConfig

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for AppConfig

Debug implementation does not leak env values (IR-41)

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for AppConfig

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for AppConfig

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Eq for AppConfig

Source§

impl JsonSchema for AppConfig

Source§

fn schema_name() -> Cow<'static, str>

The name of the generated JSON Schema. Read more
Source§

fn schema_id() -> Cow<'static, str>

Returns a string that uniquely identifies the schema produced by this type. Read more
Source§

fn json_schema(generator: &mut SchemaGenerator) -> Schema

Generates a JSON Schema for this type. Read more
Source§

fn inline_schema() -> bool

Whether JSON Schemas generated for this type should be included directly in parent schemas, rather than being re-used where possible using the $ref keyword. Read more
Source§

impl PartialEq for AppConfig

Source§

fn eq(&self, other: &AppConfig) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for AppConfig

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for AppConfig

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> DynClone for T
where T: Clone,

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.