refactor (v2): better arch
Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
19
crates/worker/Cargo.toml
Normal file
19
crates/worker/Cargo.toml
Normal file
@@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "worker"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[[bin]]
|
||||
name = "worker"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
domain = { workspace = true }
|
||||
application = { workspace = true }
|
||||
wiring = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
dotenvy = "0.15"
|
||||
tokio = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
anyhow = { workspace = true }
|
||||
38
crates/worker/src/handlers.rs
Normal file
38
crates/worker/src/handlers.rs
Normal file
@@ -0,0 +1,38 @@
|
||||
use async_trait::async_trait;
|
||||
|
||||
use application::{
|
||||
context::AppContext,
|
||||
smart::{delete_vectors, process_note},
|
||||
};
|
||||
use domain::{
|
||||
errors::DomainError,
|
||||
events::{DomainEvent, EventHandler},
|
||||
};
|
||||
|
||||
/// Routes domain events to application use cases.
|
||||
/// Smart feature use cases are skipped when the adapters are not configured
|
||||
/// (embedding and vector_store are None in AppContext).
|
||||
pub struct NoteEventHandler {
|
||||
ctx: AppContext,
|
||||
}
|
||||
|
||||
impl NoteEventHandler {
|
||||
pub fn new(ctx: AppContext) -> Self {
|
||||
Self { ctx }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl EventHandler for NoteEventHandler {
|
||||
async fn handle(&self, event: &DomainEvent) -> Result<(), DomainError> {
|
||||
match event {
|
||||
DomainEvent::NoteCreated { note_id, user_id }
|
||||
| DomainEvent::NoteUpdated { note_id, user_id } => {
|
||||
process_note::execute(&self.ctx, *note_id, *user_id).await
|
||||
}
|
||||
DomainEvent::NoteDeleted { note_id, .. } => {
|
||||
delete_vectors::execute(&self.ctx, *note_id).await
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
crates/worker/src/main.rs
Normal file
46
crates/worker/src/main.rs
Normal file
@@ -0,0 +1,46 @@
|
||||
mod handlers;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use application::worker::WorkerService;
|
||||
use domain::events::EventHandler;
|
||||
use handlers::NoteEventHandler;
|
||||
use wiring::{WiringConfig, build_context};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> anyhow::Result<()> {
|
||||
dotenvy::dotenv().ok();
|
||||
init_tracing("worker");
|
||||
|
||||
let wiring_cfg = WiringConfig::from_env()?;
|
||||
let ctx = build_context(&wiring_cfg).await?;
|
||||
|
||||
let handlers: Vec<Arc<dyn EventHandler>> = vec![Arc::new(NoteEventHandler::new(ctx.clone()))];
|
||||
|
||||
let consumer = Arc::clone(&ctx.services.event_consumer);
|
||||
let worker = WorkerService::new(consumer, handlers);
|
||||
|
||||
let (shutdown_tx, shutdown_rx) = tokio::sync::watch::channel(false);
|
||||
tokio::spawn(async move {
|
||||
tokio::signal::ctrl_c().await.ok();
|
||||
tracing::info!("shutdown signal received");
|
||||
let _ = shutdown_tx.send(true);
|
||||
});
|
||||
|
||||
tracing::info!("worker started");
|
||||
worker.run(shutdown_rx).await;
|
||||
tracing::info!("worker stopped");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn init_tracing(service: &str) {
|
||||
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
|
||||
tracing_subscriber::registry()
|
||||
.with(
|
||||
tracing_subscriber::EnvFilter::try_from_default_env()
|
||||
.unwrap_or_else(|_| format!("{service}=info").into()),
|
||||
)
|
||||
.with(tracing_subscriber::fmt::layer())
|
||||
.init();
|
||||
}
|
||||
Reference in New Issue
Block a user