forked from warlock-labs/postel
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtonic.rs
More file actions
108 lines (86 loc) · 3.33 KB
/
Copy pathtonic.rs
File metadata and controls
108 lines (86 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use std::net::SocketAddr;
use std::sync::Arc;
use hyper_util::rt::TokioExecutor;
use hyper_util::server::conn::auto::Builder as HttpConnectionBuilder;
use hyper_util::service::TowerToHyperService;
use rustls::ServerConfig;
use tokio::net::TcpListener;
use tokio_stream::wrappers::TcpListenerStream;
use tonic::server::NamedService;
use tonic::transport::Server;
use tower::ServiceExt;
use tracing::{info, Level};
use postel::{load_certs, load_private_key, serve_http_with_shutdown};
// Define a service for demonstration purposes
pub struct GreeterService;
impl NamedService for GreeterService {
const NAME: &'static str = "greeter";
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
// Initialize logging
tracing_subscriber::fmt()
.with_max_level(Level::DEBUG)
.init();
// Configure server address
let addr = SocketAddr::from(([127, 0, 0, 1], 8443));
let reflection_server = tonic_reflection::server::Builder::configure()
.register_encoded_file_descriptor_set(tonic_health::pb::FILE_DESCRIPTOR_SET)
.register_encoded_file_descriptor_set(tonic_types::pb::FILE_DESCRIPTOR_SET)
.register_encoded_file_descriptor_set(tonic_reflection::pb::v1alpha::FILE_DESCRIPTOR_SET)
.build_v1alpha()?;
// Set up gRPC health service
let (mut health_reporter, health_service) = tonic_health::server::health_reporter();
health_reporter.set_serving::<GreeterService>().await;
// Set up TCP listener
let listener = TcpListener::bind(addr).await?;
info!("Server listening on https://{}", addr);
let incoming = TcpListenerStream::new(listener);
// Create HTTP connection builder
let builder = HttpConnectionBuilder::new(TokioExecutor::new());
// Set up TLS configuration
rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.expect("Failed to install rustls crypto provider");
let certs = load_certs("examples/sample.pem")?;
let key = load_private_key("examples/sample.rsa")?;
let mut config = ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(certs, key)?;
// Configure ALPN protocols - required for gRPC
config.alpn_protocols = vec![b"h2".to_vec()];
let tls_config = Arc::new(config);
// Create a shutdown signal
let (shutdown_tx, shutdown_rx) = tokio::sync::oneshot::channel();
// Start server in the background
let server = tokio::spawn(async move {
info!("Server starting up...");
let svc = Server::builder()
.add_service(health_service)
.add_service(reflection_server)
.into_service()
.into_axum_router()
.into_service()
.boxed_clone();
let hyper_svc = TowerToHyperService::new(svc);
serve_http_with_shutdown(
hyper_svc,
incoming,
builder,
Some(tls_config),
Some(async {
shutdown_rx.await.ok();
info!("Shutdown signal received");
}),
)
.await
.expect("Server failed unexpectedly");
});
// Keep the main thread running until Ctrl+C
tokio::signal::ctrl_c().await?;
info!("Initiating graceful shutdown");
let _ = shutdown_tx.send(());
// Wait for server to shutdown
server.await?;
Ok(())
}