oa_gateway_owp::server

Struct OwpAdapter

Source
pub struct OwpAdapter {
    id: AdapterId,
    config: OwpConfig,
    conn_seq: AtomicU64,
    schema: Option<Arc<Schema>>,
    tls: Option<ServerTls>,
    connections: Arc<Semaphore>,
    at_capacity: AtomicBool,
}
Expand description

OWP/WebSocket server adapter.

Self::new does not bind. Self::serve takes a listener the host already bound. A compiled UCI schema is optional and is attached with Self::with_schema.

Fields§

§id: AdapterId§config: OwpConfig§conn_seq: AtomicU64§schema: Option<Arc<Schema>>§tls: Option<ServerTls>§connections: Arc<Semaphore>

One permit per allowed connection, held for the life of the session.

§at_capacity: AtomicBool

Set while connections are being refused, so saturation is logged on the way in and on the way out instead of once per rejected connection.

Implementations§

Source§

impl OwpAdapter

Source

pub fn new(id: impl Into<AdapterId>, config: OwpConfig) -> Self

Builds an adapter that is not yet listening.

The connection semaphore is sized from OwpConfig::max_connections. No schema is attached until Self::with_schema, and the listener is plaintext until Self::with_tls.

Source

pub fn with_schema(self, schema: Arc<Schema>) -> Self

Supply the UCI schema used to convert between OMS JSON and UCI XML.

Without one the adapter still routes, but it cannot convert: XML payloads keep their topic as the type hint and are forwarded verbatim. A schema is mandatory for OwpConfig::xml_baseline, which the host enforces at startup so the failure surfaces before any traffic arrives.

Source

pub fn with_tls(self, tls: ServerTls) -> Self

Terminate TLS on every accepted connection.

Without this the listener stays plaintext, which is unchanged behavior for a deployment that configures no certificate.

Source

pub fn id(&self) -> &AdapterId

Source

pub fn config(&self) -> &OwpConfig

Source

pub async fn serve( self: Arc<Self>, listener: TcpListener, engine: Arc<Engine>, shutdown: CancellationToken, ) -> Result<(), AdapterError>

Accepts connections on listener until shutdown is cancelled.

A failed accept is logged and the loop continues. At the connection limit the TCP stream is dropped immediately; the saturation warning is logged once on the way in and once on the way out, not once per refused peer.

§Errors

Returns AdapterError::Io if the local address of listener cannot be read. Handshake and session failures do not fail serve.

Source

async fn handle_connection( &self, stream: TcpStream, peer: SocketAddr, conn_id: u64, engine: Arc<Engine>, shutdown: CancellationToken, ) -> Result<(), AdapterError>

Handshakes one TCP stream and runs its OWP session.

A failed WebSocket handshake is logged and returns Ok, so a bad client does not take the accept loop down. Oversized frames are rejected by the WebSocket cap before the payload is fully buffered.

Source§

impl OwpAdapter

Source

pub(crate) async fn bind_and_serve( self: Arc<Self>, engine: Arc<Engine>, shutdown: CancellationToken, ) -> Result<(), AdapterError>

One bind-and-accept session: the unit Adapter::run’s retry loop restarts on failure or panic.

Trait Implementations§

Source§

impl Adapter for OwpAdapter

Source§

fn run<'async_trait>( self: Arc<Self>, engine: Arc<Engine>, shutdown: CancellationToken, ) -> Pin<Box<dyn Future<Output = Result<(), AdapterError>> + Send + 'async_trait>>
where Self: 'async_trait,

Binds the configured address and accepts connections until shutdown is cancelled, retrying a bind failure, a session error, or a session panic per OwpConfig::on_panic and OwpConfig::reconnect.

Each attempt runs on its own child task, so a panic in the accept loop is a join error here rather than an unwind that would otherwise take the retry loop down with it.

§Errors

Returns AdapterError::Io if the address cannot be bound and OwpConfig::reconnect is off. Per-connection session errors are handled inside the accept loop and never reach here.

Source§

fn id(&self) -> &AdapterId

Stable id for this adapter instance. Read more

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.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> Same for T

Source§

type Output = T

Should always be Self
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.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more