pub(crate) struct ContainerIO {
terminal: Option<Terminal>,
logger: Arc<Mutex<ContainerLog>>,
attach: SharedContainerAttach,
stdout: StdioChannel,
stderr: StdioChannel,
consumed: Arc<AtomicBool>,
collector: Mutex<Option<StdioCollector>>,
}Expand description
The stdio of a container or exec, a terminal or pipes, and the log drivers and attach endpoints its output goes to.
Fields§
§terminal: Option<Terminal>None for a process with pipes.
logger: Arc<Mutex<ContainerLog>>§attach: SharedContainerAttach§stdout: StdioChannelThe stdio channels, see StdioSender. A terminal merges stderr
into stdout, its stderr channel ends right away.
stderr: StdioChannel§consumed: Arc<AtomicBool>Whether a consumer reads the stdio channels, see StdioSender.
collector: Mutex<Option<StdioCollector>>Collects the output of an exec while its runtime runs, see
ContainerIO::collect_stdio. Taken by the consumer of the output,
which shares the IO with others already.
Implementations§
Source§impl ContainerIO
impl ContainerIO
Sourcepub(super) const IDLE_FLUSH: Duration
pub(super) const IDLE_FLUSH: Duration
How long a line without its ending waits before it is written as a partial one, so that prompts and progress output show up in the logs.
Sourcepub(crate) fn connect_streams(
&mut self,
stdin: Option<ChildStdin>,
stdout: Option<ChildStdout>,
stderr: Option<ChildStderr>,
token: CancellationToken,
)
pub(crate) fn connect_streams( &mut self, stdin: Option<ChildStdin>, stdout: Option<ChildStdout>, stderr: Option<ChildStderr>, token: CancellationToken, )
Read the pipes of the runtime, which the process it starts shares.
Sourcepub(crate) async fn connect_terminal(
&mut self,
stdin: bool,
token: CancellationToken,
) -> Result<()>
pub(crate) async fn connect_terminal( &mut self, stdin: bool, token: CancellationToken, ) -> Result<()>
Wait until the runtime connected the terminal and read it. A wait which gets dropped leaves the connection for the next one.
Sourcepub(super) fn spawn_read_loop<T>(
&mut self,
reader: T,
pipe: Pipe,
output: Arc<AttachOutput>,
)
pub(super) fn spawn_read_loop<T>( &mut self, reader: T, pipe: Pipe, output: Arc<AttachOutput>, )
Spawn the ContainerIO::read_loop of a pipe, which takes the
sender of its stdio channel.
Sourcefn spawn_stdin_loop<T>(&self, writer: Option<T>, token: CancellationToken)
fn spawn_stdin_loop<T>(&self, writer: Option<T>, token: CancellationToken)
Spawn the ContainerIO::read_loop_stdin of the process. Without a
stdin, attach clients must not wait for one which nothing ever reads.
Sourcepub(crate) async fn read_loop<T>(
reader: T,
pipe: Pipe,
logger: Arc<Mutex<ContainerLog>>,
message_tx: Option<StdioSender>,
attach: SharedContainerAttach,
attach_output: Arc<AttachOutput>,
) -> Result<()>where
T: AsyncRead + Unpin,
pub(crate) async fn read_loop<T>(
reader: T,
pipe: Pipe,
logger: Arc<Mutex<ContainerLog>>,
message_tx: Option<StdioSender>,
attach: SharedContainerAttach,
attach_output: Arc<AttachOutput>,
) -> Result<()>where
T: AsyncRead + Unpin,
Read the pipe until it ends and let the log drivers write what they still buffer, however the loop ended.
async fn read_pipe<T>(
reader: T,
pipe: Pipe,
logger: &Arc<Mutex<ContainerLog>>,
log_has_drivers: bool,
message_tx: Option<StdioSender>,
attach: &SharedContainerAttach,
) -> Result<()>where
T: AsyncRead + Unpin,
Sourceasync fn read_chunk<T>(reader: &mut T) -> Result<Bytes>where
T: AsyncRead + Unpin,
async fn read_chunk<T>(reader: &mut T) -> Result<Bytes>where
T: AsyncRead + Unpin,
Read a chunk of up to READ_BUFFER_SIZE into the scratch buffer of
the thread, see with_scratch, and copy it out. Empty once the
output ended.
Sourceasync fn closed(message_tx: Option<&StdioSender>)
async fn closed(message_tx: Option<&StdioSender>)
Complete once the stdio channel got closed, never without one.
Sourceasync fn forward(message_tx: &mut Option<StdioSender>, message: Message)
async fn forward(message_tx: &mut Option<StdioSender>, message: Message)
Forward a message to the stdio channel, see StdioSender. If the
channel got closed or all receivers are gone (see
ContainerIO::drop_stdio), the sender is dropped as well so that the
channel buffer gets freed and no further sends are attempted.
Sourcepub(crate) async fn read_loop_stdin(
writer: impl AsyncWrite + Unpin,
attach: SharedContainerAttach,
token: CancellationToken,
) -> Result<()>
pub(crate) async fn read_loop_stdin( writer: impl AsyncWrite + Unpin, attach: SharedContainerAttach, token: CancellationToken, ) -> Result<()>
Write the stdin of the attach endpoints to writer until they closed
it or the process exited, which cancels token.
async fn forward_stdin( writer: impl AsyncWrite + Unpin, attach: &SharedContainerAttach, ) -> Result<()>
Sourceasync fn handle_stdin_data(
data: &[u8],
writer: impl AsyncWrite + Unpin,
) -> Result<bool>
async fn handle_stdin_data( data: &[u8], writer: impl AsyncWrite + Unpin, ) -> Result<bool>
Write attach input to the stdin of the process, false once that got
closed, which ends the stdin like its EOF. A pipe reports EPIPE once
the process exited or closed its stdin. A terminal reports EIO only
once nothing has it open, see connect_terminal, otherwise its writes
block once its buffer is full, until the exit ends the stdin, see
read_loop_stdin.
Source§impl ContainerIO
impl ContainerIO
Sourcepub(crate) fn stdio(&self) -> Result<(Receiver<Message>, Receiver<Message>)>
pub(crate) fn stdio(&self) -> Result<(Receiver<Message>, Receiver<Message>)>
Retrieve clones of the stdout and stderr channels.
Fails if the channels have been dropped via ContainerIO::drop_stdio.
Sourcefn receivers(&self) -> Result<(&Receiver<Message>, &Receiver<Message>)>
fn receivers(&self) -> Result<(&Receiver<Message>, &Receiver<Message>)>
The stdout and stderr receivers, see ContainerIO::stdio.
Sourcepub(crate) fn drop_stdio(&mut self)
pub(crate) fn drop_stdio(&mut self)
Drop the stdout and stderr channels.
The channels buffer the last chunks per pipe for consumers like
exec_sync, which may start reading after the process already produced
output, and for reporting the runtime’s stderr if a create fails. Once
a container is created nothing consumes them anymore, attach sessions
use the attach broadcast, so they get dropped, see
StdioChannel::close.
Sourcepub(crate) fn collect_stdio(
&self,
stdout_enabled: bool,
stderr_enabled: bool,
) -> Result<()>
pub(crate) fn collect_stdio( &self, stdout_enabled: bool, stderr_enabled: bool, ) -> Result<()>
Read the output of an exec from now on, until it gets taken with
ContainerIO::take_early_stdio once its runtime finished. The
process may write a lot before, which the channels alone would drop,
see StdioSender. A runtime without a terminal shares the pipes,
so the reads must not wait for anything: they apply backpressure,
but take everything up to ContainerIO::MAX_STDIO_STREAM_SIZE per
pipe and drop what follows.
The output of a pipe which is not of interest gets read and dropped.
Sourcepub(super) async fn collect(
receiver: &Receiver<Message>,
stop: &CancellationToken,
enabled: bool,
) -> EarlyStream
pub(super) async fn collect( receiver: &Receiver<Message>, stop: &CancellationToken, enabled: bool, ) -> EarlyStream
Collect the output of a channel until stop, the remaining messages
stay queued for the consumer which comes next. Beyond the size limit
the output gets read and dropped.
Sourcepub(crate) async fn take_early_stdio(&self) -> EarlyStdio
pub(crate) async fn take_early_stdio(&self) -> EarlyStdio
The output collected since ContainerIO::collect_stdio, empty
without that.
Sourcefn consume_stdio(&self)
fn consume_stdio(&self)
Apply backpressure to the read loops from now on, see
StdioSender.
Sourcepub(crate) async fn runtime_error(&self, e: Error) -> Error
pub(crate) async fn runtime_error(&self, e: Error) -> Error
Attach the stderr output of a runtime which failed to its error. With
a terminal, the error carries it already. The read loops get stopped
afterwards, a process which the runtime left behind, like a daemon of
the process it started, may keep the pipes open, see
SharedContainerAttach::stop_output.
Sourcepub(crate) async fn read_all(
&self,
exited: &CancellationToken,
) -> Result<(Vec<u8>, Vec<u8>)>
pub(crate) async fn read_all( &self, exited: &CancellationToken, ) -> Result<(Vec<u8>, Vec<u8>)>
Read the output until it ended. Once exited got cancelled, the
output still in flight is taken as long as the Drain does. A
background process which holds the pipes open must not keep this
waiting. The channels get closed afterwards, so that the read loops
discard what follows. There is no deadline of its own: the watcher of
an exec cancels exited also when it kills the process at its
timeout, and a deadline which raced that one would end the output of
a process which exited right at it.
Sourceasync fn read_all_with_early(
&self,
exited: &CancellationToken,
early: EarlyStdio,
) -> Result<(Vec<u8>, Vec<u8>)>
async fn read_all_with_early( &self, exited: &CancellationToken, early: EarlyStdio, ) -> Result<(Vec<u8>, Vec<u8>)>
Read the output after the one collected before, see
ContainerIO::read_all.
Sourcepub(super) async fn read_stream(
exited: &CancellationToken,
receiver: &Receiver<Message>,
early: EarlyStream,
) -> Vec<u8> ⓘ
pub(super) async fn read_stream( exited: &CancellationToken, receiver: &Receiver<Message>, early: EarlyStream, ) -> Vec<u8> ⓘ
Read a stream, after the early output collected before.
Source§impl ContainerIO
impl ContainerIO
Sourcepub(crate) fn terminal(&self) -> Option<&Terminal>
pub(crate) fn terminal(&self) -> Option<&Terminal>
The terminal of the process, none with pipes.
Sourcepub(crate) fn logger(&self) -> &Arc<Mutex<ContainerLog>> ⓘ
pub(crate) fn logger(&self) -> &Arc<Mutex<ContainerLog>> ⓘ
The log drivers which get the output.
Sourcepub(crate) fn attach(&self) -> &SharedContainerAttach
pub(crate) fn attach(&self) -> &SharedContainerAttach
The attach endpoints of the process.
Sourcepub(crate) fn resize(&self, width: u16, height: u16) -> Result<()>
pub(crate) fn resize(&self, width: u16, height: u16) -> Result<()>
Resize the terminal. Errors in case of no terminal containers.
Sourcepub(crate) fn try_resize(&self, width: u16, height: u16) -> Result<bool>
pub(crate) fn try_resize(&self, width: u16, height: u16) -> Result<bool>
Resize the terminal if the container has one and return whether it
does. One which the runtime did not connect yet gets the size once
it does, see TerminalResizer::resize.
Sourcepub(crate) fn terminal_eof(&self) -> Option<u8>
pub(crate) fn terminal_eof(&self) -> Option<u8>
The end of file character of the terminal, none without one.
Source§impl ContainerIO
impl ContainerIO
Sourcepub(crate) const MAX_STDIO_STREAM_SIZE: usize
pub(crate) const MAX_STDIO_STREAM_SIZE: usize
The most output of a pipe an exec collects while its runtime runs,
see ContainerIO::collect_stdio, and the most an exec_sync
reads of each pipe.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for ContainerIO
impl !RefUnwindSafe for ContainerIO
impl !UnwindSafe for ContainerIO
impl Send for ContainerIO
impl Sync for ContainerIO
impl Unpin for ContainerIO
impl UnsafeUnpin for ContainerIO
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
§impl<T> FutureExt for T
impl<T> FutureExt for T
§fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ
§fn with_current_context(self) -> WithContext<Self> ⓘ
fn with_current_context(self) -> WithContext<Self> ⓘ
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request§impl<L> LayerExt<L> for L
impl<L> LayerExt<L> for L
§fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>where
L: Layer<S>,
Layered].