Crate oa_gateway_adapter

Source
Expand description

Adapter contract. Protocol plugins implement Adapter and talk only to oa_gateway_core::Engine — never to each other.

An adapter owns one side of the gateway: its socket, its framing, its handshake, and any schema translation. What it hands the engine is an Envelope addressed by a RouteKey, with the payload left opaque. See docs/writing-an-adapter.md for the full walkthrough; the shape is:

use async_trait::async_trait;
use oa_gateway_adapter::{Adapter, AdapterError};
use oa_gateway_core::{
    AdapterId, Delivery, Engine, Envelope, RouteKey, SubId, DEFAULT_CHANNEL_CAPACITY,
};
use tokio::sync::mpsc;
use tokio_util::sync::CancellationToken;

/// Stands in for a real protocol: answers every `Ping` on `demo` with a `Pong`.
struct Echo {
    id: AdapterId,
}

#[async_trait]
impl Adapter for Echo {
    fn id(&self) -> &AdapterId {
        &self.id
    }

    async fn run(
        self: Arc<Self>,
        engine: Arc<Engine>,
        shutdown: CancellationToken,
    ) -> Result<(), AdapterError> {
        // Deliveries arrive on a channel this adapter owns.
        let (tx, mut rx) = mpsc::channel::<Delivery>(DEFAULT_CHANNEL_CAPACITY);
        engine
            .subscribe(
                self.id.clone(),
                SubId::new("echo-1"),
                RouteKey::typed("demo", "Ping"),
                tx,
            )
            .await
            .map_err(|err| AdapterError::failed(&self.id, err.to_string()))?;

        loop {
            tokio::select! {
                // Always leave the engine clean on the way out.
                _ = shutdown.cancelled() => {
                    engine.drop_adapter(self.id.clone()).await;
                    return Ok(());
                }
                delivery = rx.recv() => {
                    let Some(delivery) = delivery else { return Ok(()) };
                    let reply = Envelope::new(
                        RouteKey::typed("demo", "Pong"),
                        delivery.envelope.payload,
                    );
                    engine.publish(reply).await;
                }
            }
        }
    }
}

Modules§

  • supervise 🔒
    Shared panic and retry supervision for an adapter whose run is a loop of independent sessions (connect, bridge, disconnect; repeat).
  • TLS shared by every adapter that rides a plain TCP stream: OWP terminates it as a server, STOMP originates it as a client. Neither DDS nor loopback use this — DDS’s RTPS transport is UDP, not a stream, so ordinary TLS does not apply to it.

Enums§

  • Fatal failure of one adapter. The host logs it and leaves the others running.
  • What a session retry loop does after one session task ends.
  • What an adapter does when its session task panics.

Traits§

  • A protocol plugin that owns its I/O loop and maps native frames onto envelopes.

Functions§

  • Maps a joined session result onto abort, return, or retry.