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: AtomicBoolSet 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
impl OwpAdapter
Sourcepub fn new(id: impl Into<AdapterId>, config: OwpConfig) -> Self
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.
Sourcepub fn with_schema(self, schema: Arc<Schema>) -> Self
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.
Sourcepub fn with_tls(self, tls: ServerTls) -> Self
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.
pub fn id(&self) -> &AdapterId
pub fn config(&self) -> &OwpConfig
Sourcepub async fn serve(
self: Arc<Self>,
listener: TcpListener,
engine: Arc<Engine>,
shutdown: CancellationToken,
) -> Result<(), AdapterError>
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.
Sourceasync fn handle_connection(
&self,
stream: TcpStream,
peer: SocketAddr,
conn_id: u64,
engine: Arc<Engine>,
shutdown: CancellationToken,
) -> Result<(), AdapterError>
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
impl OwpAdapter
Sourcepub(crate) async fn bind_and_serve(
self: Arc<Self>,
engine: Arc<Engine>,
shutdown: CancellationToken,
) -> Result<(), AdapterError>
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
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,
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.