Fundamental_Analysis/services/report-generator-service/src/state.rs
Lv, Qi 70b30b39d8 Refactor: Complete transition from analysis_results to workflow_history
- Removed dependencies on analysis_results table
- Implemented workflow_history storage in Data Persistence Service
- Updated Workflow Orchestrator to save workflow snapshots to history
- Refactored Frontend to consume workflow_history and fetch reports via VGCS
- Fixed Data Providers (Tushare, YFinance) to report output paths in metadata
- Updated documentation and task status
2025-11-29 17:55:54 +08:00

64 lines
1.8 KiB
Rust

use std::sync::Arc;
use dashmap::DashMap;
use tera::Tera;
use tokio::sync::broadcast;
use uuid::Uuid;
use common_contracts::observability::TaskProgress;
use crate::{config::AppConfig, templates::load_tera};
#[derive(Clone)]
pub struct AppState {
pub tasks: Arc<DashMap<Uuid, TaskProgress>>,
pub streams: Arc<StreamManager>,
pub config: Arc<AppConfig>,
#[allow(dead_code)]
pub tera: Arc<Tera>,
pub nats: async_nats::Client,
}
pub struct StreamManager {
// Key: RequestId (Uuid)
// Value: Broadcast Sender. We send JSON strings.
pub channels: DashMap<Uuid, broadcast::Sender<String>>,
}
impl StreamManager {
pub fn new() -> Self {
Self {
channels: DashMap::new(),
}
}
pub fn get_or_create_sender(&self, request_id: Uuid) -> broadcast::Sender<String> {
self.channels.entry(request_id).or_insert_with(|| {
// Buffer size 100 messages. If lag occurs, receiver might miss messages (RecvError::Lagged).
// Since we use this for real-time text streaming, missing a chunk is bad but acceptable for "pseudo" visual if we can recover,
// but here we don't want to miss content.
// Frontend SSE usually just reconnects.
// We should probably use a larger buffer to be safe, e.g. 1000.
let (tx, _rx) = broadcast::channel(1000);
tx
}).value().clone()
}
#[allow(dead_code)]
pub fn remove_channel(&self, request_id: &Uuid) {
self.channels.remove(request_id);
}
}
impl AppState {
pub fn new(config: AppConfig, nats: async_nats::Client) -> Self {
Self {
tasks: Arc::new(DashMap::new()),
streams: Arc::new(StreamManager::new()),
config: Arc::new(config),
tera: Arc::new(load_tera()),
nats,
}
}
}