Response

The sequence of channel responses the server sends, what ends it, and what a finish with nothing before it means.

[0][bytes …]         one or more, the file
[1][error JSON …]    last, when the read failed
  • The sequence. Zero or more channel responses whose first byte is 0, each carrying a piece of the file as the proxy sent it, in order; the pieces concatenated are the file. An error, when the server sends one, is the last channel response, and the file was not read whole. The channel response finish follows the last channel response. A channel response finish that no channel response precedes states that the proxy did not serve the read.
  • The bytes. After the byte 0, the bytes of the piece, verbatim, running to the end of the payload. A file of zero bytes is exactly one channel response with nothing after the byte 0.
  • The error. After the byte 1, exactly one JSON value in the form defined on the volumes::list response page: the proxy’s error as the server received it, or the server’s own.

The channel response is defined by diverge-provider-sdk/src/endpoints/containers/agents/run/server/channel_response/read/frame.rs:

//! What a server's channel response frame carries on a read channel.

use std::fmt;

use crate::decode::Decode;
use crate::encode::{Encode, Writer};
use crate::shared::containers::read;
use crate::shared::error::Error;

/// A piece of the file, or the news that there will not be one.
///
/// A payload leads with one byte saying which — `0` for
/// [`Body`](Self::Body), `1` for [`Error`](Self::Error) — and the rest
/// is that variant's own bytes.
///
/// # How it ends
///
/// | the channel ends with | means |
/// |-----------------------|-------|
/// | bodies, then a finish | the bytes are the file |
/// | an [`Error`](Self::Error), then a finish | the file was not read, or not all of it |
///
/// Only a finish ends it. What a caller does about an error is not
/// specified here.
///
/// # The failure is this scope's, the bytes are not
///
/// [`Body`](Self::Body) carries
/// [`read::response::Frame`](crate::shared::containers::read::response::Frame),
/// which means the same thing wherever the exchange happens. The
/// [`Error`](Self::Error) beside it is the exchange's own.
#[derive(Debug, Clone, PartialEq)]
pub enum Frame<'a> {
    /// A piece of the file. Tag `0`.
    Body(read::response::Frame<'a>),
    /// A failure. Tag `1`.
    ///
    /// See [`shared::error::Error`](crate::shared::error::Error) for
    /// why it says so little.
    Error(Error),
}

/// Tag for [`Frame::Body`].
const BODY: u8 = 0;

/// Tag for [`Frame::Error`].
const ERROR: u8 = 1;

impl Encode for Frame<'_> {
    /// The ordinary JSON failure, from the half that has one. The
    /// other cannot fail.
    type Error = serde_json::Error;

    // Spelled out rather than `Self::Error`: this enum has a variant
    // called `Error`, so the associated type is ambiguous by that name.
    fn encode(
        &self,
        out: &mut Writer<'_>,
    ) -> Result<(), serde_json::Error> {
        match self {
            Frame::Body(inner) => {
                out.extend_from_slice(&[BODY]);
                // Its error is `Infallible`, and an empty match on one
                // is how you say so: there is no value to handle.
                inner.encode(out).map_err(|error| match error {})
            }
            Frame::Error(error) => {
                out.extend_from_slice(&[ERROR]);
                error.encode(out)
            }
        }
    }
}

impl<'a> Decode<'a> for Frame<'a> {
    /// Three ways to fail, and only one of them is a parse.
    type Error = FrameError;

    // Spelled out for the same reason as `encode` above.
    fn decode(bytes: &'a [u8]) -> Result<Self, FrameError> {
        let (tag, rest) = bytes.split_first().ok_or(FrameError::Empty)?;
        match *tag {
            BODY => read::response::Frame::decode(rest)
                .map(Frame::Body)
                .map_err(|error| match error {}),
            ERROR => {
                Error::decode(rest).map(Frame::Error).map_err(FrameError::Error)
            }
            tag => Err(FrameError::UnknownTag(tag)),
        }
    }
}

/// A read response frame that could not be read.
#[derive(Debug)]
pub enum FrameError {
    /// No bytes at all, so not even a tag.
    Empty,
    /// A tag that is neither of this frame's two.
    UnknownTag(u8),
    /// The error did not parse.
    Error(serde_json::Error),
}

impl fmt::Display for FrameError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            FrameError::Empty => f.write_str("read response frame is empty"),
            FrameError::UnknownTag(tag) => {
                write!(f, "unknown read response frame tag {tag}")
            }
            FrameError::Error(error) => {
                write!(f, "read error did not parse: {error}")
            }
        }
    }
}

impl std::error::Error for FrameError {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        match self {
            FrameError::Error(error) => Some(error),
            FrameError::Empty | FrameError::UnknownTag(_) => None,
        }
    }
}

and by diverge-provider-sdk/src/shared/containers/read/response/frame.rs:

//! What a response frame carries on a read channel.

use std::convert::Infallible;

use crate::decode::Decode;
use crate::encode::{Encode, Writer};

/// A piece of the file.
///
/// Bytes and nothing else — no tag, because there is nothing to
/// discriminate. A read channel carries one kind of traffic from the
/// first byte to the last, and the requester knew what it was when it
/// asked.
///
/// # How it ends
///
/// With a finish, and only with a finish. There is no `Complete` and
/// there is no failure: a read that finished cleanly is one whose
/// channel finished —
/// [`ChannelResponseFinish`](crate::frame::server::ServerFrame::ChannelResponseFinish)
/// says so at the frame layer, and saying it again in the payload
/// would be two signals for one fact.
///
/// # A silent tear is possible here
///
/// A file being read can be written underneath the reader, and the
/// bytes already sent are then a mix: whatever was there before the
/// write, and whatever is there after.
///
/// A provider can DETECT it — `fstat` on its own descriptor before the
/// first byte and after the last, comparing size and mtime — and
/// cannot prevent it. Linux advisory locks bind only processes that
/// opt in, and mandatory locking was removed in 5.15. But there is no
/// frame here that means "here are the bytes, and they moved while I
/// sent them", so a provider that detects one has nowhere to say so.
///
/// # No length, anywhere
///
/// Not in a head, not in the request, not implied by anything. A file
/// being written to can change size in both directions after a sender
/// has looked at it, so any length stated up front is a promise made
/// about a number that has already moved. It is the commitment that
/// makes `tar` corrupt a whole archive when one entry shifts, and this
/// declines to make it.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
pub struct Frame<'a>(
    /// The bytes, borrowed from the frame they arrived in.
    ///
    /// Sent as they are read. A sender holds no more than one buffer's
    /// worth, so a file larger than memory crosses without either end
    /// ever holding it whole.
    pub &'a [u8],
);

/// Straight through, and identical to
/// [`write_bytes`](crate::shared::containers::write_bytes::response::Frame)
/// — which is what makes piping a read into a write cost nothing. One
/// frame out is one frame in, with no shape to translate between
/// them; whatever tag an endpoint puts in front is a byte, not a
/// copy.
impl Encode for Frame<'_> {
    /// [`Infallible`]: copying a slice into a buffer has no failure
    /// mode.
    type Error = Infallible;

    fn encode(&self, out: &mut Writer<'_>) -> Result<(), Self::Error> {
        out.extend_from_slice(self.0);
        Ok(())
    }
}

impl<'a> Decode<'a> for Frame<'a> {
    /// [`Infallible`]: there is nothing to get wrong about a slice
    /// that is already the answer.
    type Error = Infallible;

    fn decode(bytes: &'a [u8]) -> Result<Self, Self::Error> {
        Ok(Frame(bytes))
    }
}