Skip to main content

PersistentChild

Struct PersistentChild 

Source
pub struct PersistentChild {
    pub stdin: Option<PersistentWriter>,
    /* private fields */
}
Expand description

A child process that will persist over multiple reload cycles.

This child makes use of interprocess’s local sockets for communication. This is because the process will be spawned by the duat executor, and communication between it and the config child process won’t be possible by regular stdio.

Unless you call PersistentChild::kill, duat will assume that you want it to be kept alive for future reloads.

§Later retrieval

If you want to retrieve this PersistentChild on a future reload cycle. You will need to store it by calling storage::store, from duat’s storage module. You can only do this once, trying it again will (logically) cause a panic.

Since this struct implements Decode and Encode, it can be stored and retrieved, even if it is part of another struct.

If you don’t call storage::store, it is assumed that you no longer need the process, and it will be killed.

§Unread bytes

When reloading Duat, the stdin, stdout and stderr processes are guaranteed to not lose any bytes.

This is only the case, however, if you don’t have some sort of buffering and/or aren’t doing a deserialization attempt with said data.

If you want to do deserialization (via Decode), you will want to use PersistentReader::decode_bytes_as. This method will fail to decode if a reload is requested midway through reading, but the bytes will be saved for the next reload cycle, where you can start decoding again.

Fields§

§stdin: Option<PersistentWriter>

The standard input of the Child.

This struct will send the bytes to an ipc enabled LocalSocketStream, which will in turn be sent to the process indirectly, since said process is owned by the parent executor, not the child.

Implementations§

Source§

impl PersistentChild

Source

pub fn get_stdout(&self) -> Option<PersistentReader>

The standard output of the Child.

This reader is already buffered, so you don’t need to wrap it in a BufReader to use it efficiently.

In order to use this correctly, you must follow one of three scenarios:

  • A reading loop that never stops. This is the most common usecase.
  • If you are going to stop, make sure that the reader is dropped or that you have called PersistentReader::give_back. This is to ensure that any unread bytes are stored correctly when reloading Duat.
  • If the child has been killed, then you don’t need to do anything in particular.

For decoding bincode::Decode types, you should make use of the PersistentReader::decode_bytes_as function, since that one is not prone to losses if it is interrupted by a reload.

Source

pub fn get_stderr(&self) -> Option<PersistentReader>

The standard error of the Child.

This reader is already buffered, so you don’t need to wrap it in a BufReader to use it efficiently.

In order to use this correctly, you must follow one of three scenarios:

  • A reading loop that never stops. This is the most common usecase.
  • If you are going to stop, make sure that the reader is dropped or that you have called PersistentReader::give_back. This is to ensure that any unread bytes are stored correctly when reloading Duat.
  • If the child has been killed, then you don’t need to do anything in particular.
Source

pub fn kill(self) -> Result<()>

Kill the Child process.

Trait Implementations§

Source§

impl<Context> Decode<Context> for PersistentChild

Source§

fn decode<D: Decoder<Context = Context>>( decoder: &mut D, ) -> Result<Self, DecodeError>

Attempt to decode this type with the given Decode.
Source§

impl Drop for PersistentChild

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl Encode for PersistentChild

Source§

fn encode<E: Encoder>(&self, encoder: &mut E) -> Result<(), EncodeError>

Encodes the PersistentChild

This can only be done once, trying to do it again will result in a panic.

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> 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, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

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.