Skip to main content

ProcessInfo

Struct ProcessInfo 

Source
#[non_exhaustive]
pub struct ProcessInfo {
Show 20 fields pub id: u32, pub name: String, pub status: ProcStatus, pub pid: Option<u32>, pub restarts: u32, pub uptime_ms: u64, pub fold: Option<String>, pub out_file: Option<String>, pub err_file: Option<String>, pub cpu_percent: Option<f32>, pub memory_bytes: Option<u64>, pub dog: Option<DogSource>, pub lambs: Option<Vec<Lamb>>, pub last_exit: Option<ExitInfo>, pub smit: Option<String>, pub instance: Option<u32>, pub handshook: Option<bool>, pub dog_stale: Option<bool>, pub pending: Option<Vec<String>>, pub overridden: Option<Vec<String>>,
}
Expand description

Snapshot of one sheep for listings and events #[non_exhaustive]: this struct grows fields over time with no hand-edit sweep needed across OUT-OF-TREE callers — it forbids a struct literal outside this crate, not inside it. sample_info() and ProcessInfoBuilder both still name every field and both still need updating the day a field is added; what the attribute buys is that nothing downstream does. deferred.md’s own ProcessInfo entry defers SPLITTING it into several smaller types, not growing it — this attribute plus ProcessInfo::builder is “deliberately the opposite of forcing the split early,” which is what makes a field like last_exit cheap to add for a concrete operator need, not a reason to withhold one. Use ProcessInfo::builder to construct one; the fields stay pub, so reading them and assigning to them are both unchanged.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§id: u32

Stable numeric id

§name: String

Sheep name

§status: ProcStatus

Lifecycle status

§pid: Option<u32>

OS pid while running

§restarts: u32

Restart count since registration

§uptime_ms: u64

Milliseconds since last successful start

§fold: Option<String>

Fold membership

§out_file: Option<String>

Resolved stdout log path: the app’s explicit AppConfig::out_file when it set one, else the daemon-derived default. None only when the peer daemon predates this field.

§err_file: Option<String>

Resolved stderr log path, resolved exactly as Self::out_file

§cpu_percent: Option<f32>

Tree CPU as a percentage of one core, over the window since the daemon’s last periodic sample. None when the sheep is not running, when it has been up for less than one sampling window, or when the peer daemon predates this field — all three of which a reader renders as unknown, never as zero.

A value over 100 is a tree using more than one core, not a bug.

§memory_bytes: Option<u64>

Tree resident set size in bytes, current as of the reply. None under the same three conditions as Self::cpu_percent, minus the window one — memory needs no baseline.

§dog: Option<DogSource>

Set when this entry is a dog, naming where the dog came from; None for a sheep.

Unlike Self::cpu_percent, None here does not need to enumerate three cases. A daemon built before dogs existed has none, so “not a dog” is the true answer whether this peer predates the field or the entry is genuinely a sheep — there is no resource-usage-style claim a stale zero could get wrong. Do not “fix” this into three cases.

§lambs: Option<Vec<Lamb>>

The processes the OS reports as descendants of this sheep, or None when this reply did not walk for them.

None covers two cases and is deliberately not a third: this reply is not a Describe (only Describe walks — the walk costs a second pass over the machine’s process table, and a flock listing is the thing an operator leaves running in a loop), or the peer daemon predates the field. Some(vec![]) is the third case, and the one that means what it looks like: walked, and this sheep has no children.

Read Lamb’s own doc before rendering this. The list is a parent-pid walk and is NOT the set of processes a stop kills; any output built from it has to say so where the operator will see it.

§last_exit: Option<ExitInfo>

How this sheep’s process most recently stopped existing under this daemon. None while it has never exited under this daemon — either it has not been started yet, or it is still on its very first run — and also when the peer daemon predates this field, the same skew rule Self::out_file documents for itself.

Sticky across a respawn, deliberately: this is the daemon’s answer to “why did it last stop”, not “is it stopped right now” — status and pid already answer that, and a sheep back Online after a crash still has a true story to tell about the crash that restarted it. It updates only on the next exit, never cleared by one starting back up.

§smit: Option<String>

The marker a dog has asked to have painted beside this sheep, or None when no dog has painted one — which also covers a peer daemon that predates the field, the same skew rule Self::out_file documents for itself.

A String rather than a Smit, deliberately: a client decoding a listing from a daemon that already validated the text should not have to re-run the parser, and ProcessInfo is a report rather than an input. The validation that makes this safe to print happened at the daemon’s ingress — see Smit for why there and not at the renderer.

Every instance of a name shows the same marker: smits are keyed by sheep name, not by instance id.

§instance: Option<u32>

Which instance slot of its app this sheep occupies, counting from 0.

None when the peer daemon predates the field, the same skew rule Self::out_file documents for itself. Deliberately not a bare u32 defaulted to 0: an app stocked to four instances would then report four rows all claiming slot 0, which is the silently-wrong zero Self::dog warns against. A reader that finds None should render exactly what it rendered before this field existed.

§handshook: Option<bool>

Whether this dog has completed a handshake with the shepherd that is reporting it, and not been refused since; None for a sheep.

Read Self::dog’s own doc first — this field follows it rather than Self::cpu_percent, and for the same reason. None covers a sheep and a peer daemon that predates the field, and collapsing the two costs nothing: a sheep never handshakes with anything (it has no connection to the shepherd at all, only a supervised process), so “no handshake fact to report” is the true answer either way, and a reader that finds None renders exactly what it rendered before this field existed. Do not “fix” this into three cases.

Some(false) is the one that matters and it is why this exists. Self::status reports whether a PROCESS is alive, which for a sheep is the whole truth and for a dog is not: a dog that cannot talk to the shepherd is not doing its job, however alive it is. A dog running on a protocol this shepherd refuses is exactly that, and before this field a listing reported it online with zero restarts while its own log filled with refusals.

A fact and not a verdict, deliberately: this says whether the handshake happened, never what a renderer should print about it. A dog that has only just been spawned has not handshaken yet and is perfectly healthy, so the decision about which lifecycle states that silence is worth overriding belongs to the reader.

§dog_stale: Option<bool>

Whether the reporting shepherd has GIVEN UP on this dog — restarted it once for never answering, watched that not help, and stopped restarting it; None for a sheep.

The same None rule Self::handshook documents, for the same reason: a sheep is never given up on because a sheep never had to answer anything, so “no verdict to report” is the true answer both for a sheep and for a peer daemon that predates this field, and a reader that finds None renders exactly what it rendered before the field existed. Do not “fix” this into three cases.

Why this is not derivable from Self::handshook, which is the whole reason it exists. Some(false) there covers two dogs whose rows are otherwise identical: one spawned three seconds ago that has simply not dialled back yet, and one this shepherd has permanently stopped restarting. The first needs nothing done about it and the second is an incident. Before this field the give-up was a latch inside the daemon that no listing could see, so every operator-facing surface rendered both as the same word.

A fact and not a verdict, again deliberately. It says the shepherd stopped, never why — the why is what the shepherd wrote into that dog’s own log when it gave up, and it is the one place that can name the evidence (shep bleats <dog>). A renderer that invented a cause here would be re-committing the bug this field was added during: a shepherd asserting a cause it never observed.

§pending: Option<Vec<String>>

The AppConfig field NAMES this sheep’s spec differs from a load’s parked config for, in field-name order. None when nothing is parked (every sheep outside the window between a load that changed a NeedsRespawn field and the restart that picks it up), and also when the peer daemon predates the field, the same skew rule Self::out_file documents for itself.

Names only, never values, for the same reason SheepDrift::fields carries names only: a differing env reports "env" and stops there (IR-41). shep reload is what promotes a parked config.

#[serde(skip_serializing_if = "Option::is_none")]: most sheep are not mid-parking, so this keeps the ordinary reply free of a key that would otherwise be null on almost every row.

§overridden: Option<Vec<String>>

The AppConfig field NAMES an operator has set on this sheep that its current Flockfile does not declare, in field-name order. None when there is nothing to report: no override on record for this sheep, or a peer daemon that predates the field.

Names only, never values, for the reason Self::pending gives: crate::overrides::AppOverrides::fields can hold an env value, and nothing in shep sends an app’s env to a client (IR-41).

#[serde(skip_serializing_if = "Option::is_none")], for the same reason Self::pending carries it: most sheep carry no override at all.

Implementations§

Source§

impl ProcessInfo

Source

pub fn builder( id: u32, name: impl Into<String>, status: ProcStatus, ) -> ProcessInfoBuilder

Starts a builder for one sheep’s row.

The three required arguments are the three fields no row can omit and no reader can default: which sheep this is, what it is called, and what state it is in. Everything else is optional, derived, or meaningfully absent, which is exactly the shape a builder is for — a nine-argument new would put Option<String>, Option<String>, Option<f32>, Option<u64> next to each other at every call site and invite a silent transposition the type system could not catch.

No #[must_use] here: ProcessInfoBuilder already carries one, which clippy’s double_must_use lint treats as covering this function’s return too.

Trait Implementations§

Source§

impl Clone for ProcessInfo

Source§

fn clone(&self) -> ProcessInfo

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 ProcessInfo

Source§

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

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

impl<'de> Deserialize<'de> for ProcessInfo

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 PartialEq for ProcessInfo

Source§

fn eq(&self, other: &ProcessInfo) -> 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 ProcessInfo

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 ProcessInfo

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<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, !>

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.