/postgres/{channel}
Kind 11: one database connection the container opened, announced with no payload; the path is that connection, and it carries the PostgreSQL wire protocol verbatim in both directions until either party closes it.
The ask is kind 11 on /requests, and its
payload is empty:
[11]
The ask announces one connection that the container has opened to
its database. The server opens /postgres/{channel}, and that path
is the connection.
- Verbatim, in both directions. Every message in either direction is a chunk of the PostgreSQL wire protocol, carried verbatim: no frame, no tag, and no acknowledgement surrounds it. A message of the wire protocol may span several WebSocket messages, and several may share one; each party reassembles the bytes as it would from a socket. Neither party reads the bytes.
- The path is the connection. The opening of the path is the existence of the connection. The close of the path, clean or abrupt and by either party, is the end of the connection. No message opens the connection and no message closes it.
- Before the path opens. The proxy holds what the container’s
side wrote before the server opened the path, and sends it first,
in order, once the path is open. An announcement whose
/requestsconnection ended before the server opened its path is a connection that has ended. - No repetition. A connection that has ended is not resumed, and its bytes are not sent again. A new connection is a new announcement and a new path.
The announcement is defined by
diverge-provider-sdk/src/container_proxy/postgres/request/request.rs:
//! The announcement.
use std::convert::Infallible;
use crate::encode::{Encode, Writer};
/// A database connection the driver just opened. Kind `11` on
/// `/requests`, carrying nothing: the channel is the whole ask, and
/// the server opens `/postgres/{channel}` for it.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash)]
pub struct Request;
impl Encode for Request {
/// [`Infallible`]: nothing is written.
type Error = Infallible;
fn encode(&self, _: &mut Writer<'_>) -> Result<(), Infallible> {
Ok(())
}
}
impl Request {
/// Decode from the bytes after the ask's kind: there are none to
/// read, and any that are there are ignored.
pub fn decode(_: &[u8]) -> Result<Self, Infallible> {
Ok(Request)
}
}
A chunk from the proxy is defined by
diverge-provider-sdk/src/container_proxy/postgres/request/frame.rs:
//! A chunk of pgwire from the driver, toward the database.
use std::convert::Infallible;
use crate::encode::{Encode, Writer};
/// One message on `/postgres/{channel}` from the driver, toward the database: pgwire bytes,
/// verbatim, never parsed. A pgwire message larger than one of these
/// spans several, and the far end reassembles as from a socket.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Frame<'a>(
/// The bytes, borrowed from the message they arrived in.
pub &'a [u8],
);
impl Encode for Frame<'_> {
/// [`Infallible`]: bytes copied.
type Error = Infallible;
fn encode(&self, out: &mut Writer<'_>) -> Result<(), Infallible> {
out.extend_from_slice(self.0);
Ok(())
}
}
impl<'a> Frame<'a> {
/// Decode one message: the bytes, kept.
pub fn decode(bytes: &'a [u8]) -> Result<Self, Infallible> {
Ok(Frame(bytes))
}
}
A chunk from the server is defined by
diverge-provider-sdk/src/container_proxy/postgres/response/frame.rs:
//! A chunk of pgwire from the database, toward the driver.
use std::convert::Infallible;
use crate::encode::{Encode, Writer};
/// One message on `/postgres/{channel}` from the database, toward the driver: pgwire bytes,
/// verbatim, never parsed. A pgwire message larger than one of these
/// spans several, and the far end reassembles as from a socket.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Frame<'a>(
/// The bytes, borrowed from the message they arrived in.
pub &'a [u8],
);
impl Encode for Frame<'_> {
/// [`Infallible`]: bytes copied.
type Error = Infallible;
fn encode(&self, out: &mut Writer<'_>) -> Result<(), Infallible> {
out.extend_from_slice(self.0);
Ok(())
}
}
impl<'a> Frame<'a> {
/// Decode one message: the bytes, kept.
pub fn decode(bytes: &'a [u8]) -> Result<Self, Infallible> {
Ok(Frame(bytes))
}
}