pub struct Server { /* private fields */ }Implementations§
Source§impl Server
impl Server
pub fn builder() -> ServerBuilder
Sourcepub fn subscribe(&self) -> Receiver<ServingState>
pub fn subscribe(&self) -> Receiver<ServingState>
Subscribe to serving-state transitions.
Returns a fresh watch::Receiver observing the same ServingState
the server publishes as leadership comes and goes. Embedders use this
to gate their own startup on ServingState::Serving (see the
embedded_router and piggyback examples). Because into_router
consumes the Server, capture the receiver before mounting.
This method is the stable observation API: the receiver is minted from
the server’s watch::Sender, so the receiver’s type can evolve (e.g. a
future newtype around ServingState) without breaking embedders that
go through it.
Source§impl Server
impl Server
Sourcepub fn into_router(self) -> Result<(Routes, WatchGuard), ServerError>
pub fn into_router(self) -> Result<(Routes, WatchGuard), ServerError>
Return the configured TsoServiceServer<TsoServiceImpl> as a tonic
Routes value plus a WatchGuard for the spawned leader-watch task,
so callers can mount tsoracle’s service alongside their own services
on a shared tonic listener instead of binding a dedicated port.
The returned WatchGuard owns the leader-watch task. Keep it alive
for as long as the mounted Routes should serve: the watch task holds
an Arc<Server> (and the consensus driver) and maintains serving state
across leadership transitions. Dropping the guard — or calling
WatchGuard::shutdown — cooperatively stops the task at the embedder’s
own shutdown. Without the guard the task would keep Arc<Server> alive
until the leadership stream happened to close.
Every termination of the task — cooperative cancellation, driver error,
panic, or clean EOF on the leadership stream (surfaced as
ServerError::WatchStreamClosed) — publishes
ServingState::NotServing { leader_endpoint: None } before returning, so
all subsequent RPCs fail fast with FAILED_PRECONDITION. Embedders who
drop the guard without awaiting still get fail-safe behavior.
The Server::serve() method is a thin wrapper over this — it calls
into_router, builds a tonic Server, and binds a listener.
Returns Err(ServerError::ReflectionInit) (only reachable under the
reflection feature) if the embedded descriptor set fails to decode.
That decode happens before the leader-watch task is spawned, so a failure
leaves nothing running to clean up.
pub async fn serve(self, addr: SocketAddr) -> Result<(), ServerError>
Sourcepub async fn serve_with_shutdown(
self,
addr: SocketAddr,
shutdown: impl Future<Output = ()> + Send + 'static,
) -> Result<(), ServerError>
pub async fn serve_with_shutdown( self, addr: SocketAddr, shutdown: impl Future<Output = ()> + Send + 'static, ) -> Result<(), ServerError>
Run the gRPC server until either the caller’s shutdown fires or the
leader-watch task terminates.
Three outcomes:
shutdownfires first → tonic drains in-flights and returns Ok. The watch task is then stopped cooperatively, bounded byshutdown_graceand forcibly aborted if it overruns (e.g. parked in a wedged consensus-driver call); any error it had been about to return is forfeited (the process is shutting down anyway).- Watch returns
Ok(Err(e))→ poisoned state is already published;cancel_txtriggers tonic’s graceful shutdown; in-flightGetTscalls whosetry_grantalready succeeded complete with the timestamps they were allocated; new calls fail fast. ReturnsErr(e)— the watch error wins even if the drain itself also errors (seecombine_watch_and_drain); a drain error is surfaced only when the watch ended cleanly. - Watch task panics → returns
Err(ServerError::WatchPanic{..})with the panic payload stringified. Same drain semantics as (2).
Sourcepub async fn serve_with_listener(
self,
listener: TcpListener,
shutdown: impl Future<Output = ()> + Send + 'static,
) -> Result<(), ServerError>
pub async fn serve_with_listener( self, listener: TcpListener, shutdown: impl Future<Output = ()> + Send + 'static, ) -> Result<(), ServerError>
Run the gRPC server on a caller-provided TcpListener until either
the caller-provided shutdown fires or the leader-watch task terminates.
Use this instead of Self::serve_with_shutdown when you need to
observe the OS-picked port (127.0.0.1:0) before clients connect, or
when you want to wrap the listener in an outer adapter before passing it
in. The listening socket is owned by the caller and passed here; tsoracle
starts accepting on it immediately.
Three outcomes:
shutdownfires first → tonic drains in-flights and returnsOk. The watch handle is aborted; any error it had been about to return is forfeited (the process is shutting down anyway).- Watch returns
Ok(Err(e))→ poisoned state is already published; the caller-provided shutdown is cancelled internally so tonic begins graceful shutdown; in-flightGetTscalls whosetry_grantalready succeeded complete with the timestamps they were allocated; new calls fail fast. ReturnsErr(e)— the watch error wins even if the drain itself also errors (seecombine_watch_and_drain); a drain error is surfaced only when the watch ended cleanly. - Watch task panics → returns
Err(ServerError::WatchPanic{..})with the panic payload stringified. Same drain semantics as (2).
Auto Trait Implementations§
impl Freeze for Server
impl !RefUnwindSafe for Server
impl Send for Server
impl Sync for Server
impl Unpin for Server
impl UnsafeUnpin for Server
impl !UnwindSafe for Server
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
T in a tonic::Request