Skip to main content

Vine/Server/
SpawnBindTask.rs

1//! Spawn a detached tokio task that runs a tonic gRPC `Router` on the
2//! given address.
3//!
4//! Lifted into the Vine crate so every embedder (Mountain's
5//! `MountainVinegRPCService`, Air's `AirVinegRPCService`, any Rust-side
6//! Cocoon client) shares one bind path with consistent dev-log
7//! instrumentation.
8//!
9//! ## Why a `Router`, not a `Server` builder
10//!
11//! tonic's `Server::builder()` returns a [`tonic::transport::Server`]. After
12//! the first `.add_service(...)` call you get a
13//! [`tonic::transport::server::Router`]. The Router type carries the
14//! generic stack of registered services, which is opaque to Vine - only the
15//! embedder knows the concrete service set. So Vine accepts a constructed
16//! `Router` and runs the boilerplate.
17//!
18//! ## Lifecycle
19//!
20//! The serve future runs until either the OS socket closes or the tokio
21//! runtime shuts down. The task is detached; no `JoinHandle` is returned.
22//! Errors are logged via `dev_log!` and otherwise swallowed - the embedder
23//! decides whether to retry, restart, or fail loud via separate
24//! supervisory code.
25
26use std::net::SocketAddr;
27
28use tonic::transport::server::Router;
29
30use crate::dev_log;
31
32/// Spawn a detached tokio task that serves `Router` on `Address`.
33///
34/// # Parameters
35///
36/// * `ServerName` - label used in dev-log messages.
37/// * `Address`    - resolved socket address (callers should run
38///   [`crate::Server::ValidateSocketAddress::Fn`] first).
39/// * `Router`     - constructed tonic Router with services already added.
40///
41/// # Behaviour
42///
43/// - Emits an `info`-level dev_log on start.
44/// - Awaits `Router.serve(Address)`.
45/// - On `Ok(())`, dev_logs graceful shutdown.
46/// - On `Err`, dev_logs the error and exits the task.
47pub fn Fn(ServerName:String, Address:SocketAddr, Router:Router) {
48	tokio::spawn(async move {
49		dev_log!("grpc", "[Vine::Server] Starting {} gRPC server on {}", ServerName, Address);
50
51		let Result_ = Router.serve(Address).await;
52
53		match Result_ {
54			Ok(_) => {
55				dev_log!("grpc", "[Vine::Server] {} server shut down gracefully", ServerName);
56			},
57
58			Err(Error) => {
59				dev_log!("grpc", "error: [Vine::Server] {} gRPC server error: {}", ServerName, Error);
60			},
61		}
62	});
63}