server/worker/src/main.rs
vegard ea3b3d5a38 Fix: worker oppdaterer SpacetimeDB etter AI-behandling
Frontend leser fra SpacetimeDB, men workeren skrev kun til PG.
Nå kalles edit_message-reduceren i SpacetimeDB etter vellykket
AI-behandling, slik at resultatet vises umiddelbart i chatten.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-16 03:22:18 +01:00

117 lines
3.2 KiB
Rust

use clap::Parser;
use sqlx::postgres::PgPoolOptions;
use std::sync::Arc;
use tracing::{info, warn};
mod handlers;
mod sync;
mod warmup;
mod worker;
#[derive(Parser)]
#[command(name = "sidelinja-worker", about = "Jobbkø-worker for Sidelinja")]
struct Cli {
/// PostgreSQL connection string
#[arg(
long,
env = "DATABASE_URL",
default_value = "postgres://sidelinja:localdev@localhost:5432/sidelinja"
)]
database_url: String,
/// AI Gateway base URL
#[arg(
long,
env = "AI_GATEWAY_URL",
default_value = "http://localhost:4000/v1"
)]
ai_gateway_url: String,
/// AI Gateway API-nøkkel (LiteLLM master key)
#[arg(long, env = "AI_GATEWAY_KEY", default_value = "")]
ai_gateway_key: String,
/// Maks samtidige jobber
#[arg(long, default_value = "3")]
max_concurrent: usize,
/// Polling-intervall i sekunder
#[arg(long, default_value = "1")]
poll_interval: u64,
/// SpacetimeDB URL
#[arg(long, env = "SPACETIMEDB_URL", default_value = "http://localhost:3000")]
spacetimedb_url: String,
/// SpacetimeDB modulnavn
#[arg(long, env = "SPACETIMEDB_MODULE", default_value = "sidelinja-realtime")]
spacetimedb_module: String,
/// Sync-intervall i sekunder (SpacetimeDB → PG)
#[arg(long, default_value = "1")]
sync_interval: u64,
/// Maks meldinger per kanal ved oppvarming
#[arg(long, default_value = "100")]
warmup_limit: i64,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| "sidelinja_worker=info,sqlx=warn".into()),
)
.json()
.init();
let cli = Cli::parse();
info!(
max_concurrent = cli.max_concurrent,
poll_interval_s = cli.poll_interval,
"Starter sidelinja-worker"
);
let pool = PgPoolOptions::new()
.max_connections(cli.max_concurrent as u32 + 2)
.connect(&cli.database_url)
.await?;
info!("Tilkoblet PostgreSQL");
let registry = Arc::new(handlers::build_registry(
reqwest::Client::new(),
cli.ai_gateway_url,
cli.ai_gateway_key,
cli.spacetimedb_url.clone(),
cli.spacetimedb_module.clone(),
));
let registered: Vec<&str> = registry.keys().map(|k| k.as_str()).collect();
info!(?registered, "Registrerte jobbtyper");
// Oppvarming: last PG-data inn i SpacetimeDB
let http = reqwest::Client::new();
if let Err(e) = warmup::run(
&pool,
&http,
&cli.spacetimedb_url,
&cli.spacetimedb_module,
cli.warmup_limit,
).await {
warn!(error = %e, "Oppvarming feilet — fortsetter uten historikk i SpacetimeDB");
}
// Spawn sync-worker som parallell task
let sync_pool = pool.clone();
let spacetimedb_url = cli.spacetimedb_url.clone();
let spacetimedb_module = cli.spacetimedb_module.clone();
let sync_interval = cli.sync_interval;
tokio::spawn(async move {
sync::run(sync_pool, http, spacetimedb_url, spacetimedb_module, sync_interval).await;
});
worker::run(pool, registry, cli.max_concurrent, cli.poll_interval).await
}