chore: initial release v0.1.0
Runtime-agnostic oneshot broadcast channel for Rust.
This commit is contained in:
64 files changed
+23966
No files matched your search
@@ -0,0 +1,113 @@
|
||||
//! Lazy initialization pattern using announcement
|
||||
//!
|
||||
//! This example demonstrates using announcement to signal when
|
||||
//! a resource is ready, allowing dependent tasks to wait.
|
||||
//!
|
||||
//! Run with: cargo run --example lazy_init
|
||||
|
||||
use announcement::Announcement;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tokio::time::sleep;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct DatabaseConnection {
|
||||
connection_string: String,
|
||||
pool_size: usize,
|
||||
}
|
||||
|
||||
impl DatabaseConnection {
|
||||
async fn connect(connection_string: String) -> Self {
|
||||
println!("Database: Connecting to {}...", connection_string);
|
||||
|
||||
// Simulate connection establishment
|
||||
sleep(Duration::from_millis(800)).await;
|
||||
|
||||
println!("Database: Connection established");
|
||||
Self {
|
||||
connection_string,
|
||||
pool_size: 10,
|
||||
}
|
||||
}
|
||||
|
||||
fn execute_query(&self, query: &str) -> String {
|
||||
format!(
|
||||
"Query '{}' executed on {} [pool: {}]",
|
||||
query, self.connection_string, self.pool_size
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
// Create announcement for database connection
|
||||
let (db_announcer, db_announcement) = Announcement::new();
|
||||
|
||||
// Multiple services that need the database
|
||||
let api_service = tokio::spawn({
|
||||
let db_listener = db_announcement.listener();
|
||||
async move {
|
||||
println!("API Service: Starting up...");
|
||||
println!("API Service: Waiting for database connection...");
|
||||
|
||||
// Wait for database to be ready
|
||||
let db: Arc<DatabaseConnection> = db_listener.listen().await.unwrap();
|
||||
|
||||
println!("API Service: Database ready, processing requests");
|
||||
let result = db.execute_query("SELECT * FROM users");
|
||||
println!("API Service: {}", result);
|
||||
}
|
||||
});
|
||||
|
||||
let background_worker = tokio::spawn({
|
||||
let db_listener = db_announcement.listener();
|
||||
async move {
|
||||
println!("Background Worker: Starting up...");
|
||||
println!("Background Worker: Waiting for database connection...");
|
||||
|
||||
let db: Arc<DatabaseConnection> = db_listener.listen().await.unwrap();
|
||||
|
||||
println!("Background Worker: Database ready, starting jobs");
|
||||
let result = db.execute_query("UPDATE jobs SET status = 'running'");
|
||||
println!("Background Worker: {}", result);
|
||||
}
|
||||
});
|
||||
|
||||
let metrics_collector = tokio::spawn({
|
||||
let db_listener = db_announcement.listener();
|
||||
async move {
|
||||
println!("Metrics Collector: Starting up...");
|
||||
|
||||
// Try polling first (non-blocking check)
|
||||
if db_listener.try_listen().is_none() {
|
||||
println!("Metrics Collector: Database not ready yet, waiting...");
|
||||
let db: Arc<DatabaseConnection> = db_listener.listen().await.unwrap();
|
||||
println!("Metrics Collector: Database ready");
|
||||
let result = db.execute_query("INSERT INTO metrics VALUES (...)");
|
||||
println!("Metrics Collector: {}", result);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Simulate initialization work before database connection
|
||||
println!("Main: Initializing application...");
|
||||
sleep(Duration::from_millis(200)).await;
|
||||
|
||||
// Now establish the database connection
|
||||
println!("\nMain: Starting database initialization...\n");
|
||||
let db = DatabaseConnection::connect("postgresql://localhost:5432/myapp".to_string()).await;
|
||||
|
||||
// Wrap in Arc for efficient sharing
|
||||
let db = Arc::new(db);
|
||||
|
||||
// Announce that database is ready
|
||||
// All waiting services will be notified simultaneously
|
||||
println!("\nMain: Broadcasting database connection...\n");
|
||||
db_announcer.announce(db.clone()).unwrap();
|
||||
|
||||
// Wait for all services to complete
|
||||
let _: (Result<(), _>, Result<(), _>, Result<(), _>) =
|
||||
tokio::join!(api_service, background_worker, metrics_collector);
|
||||
|
||||
println!("\nMain: All services initialized successfully");
|
||||
}
|
||||
Reference in new issue
Block a user