mirror of
https://github.com/Portabase/agent.git
synced 2026-09-10 01:57:10 +00:00
feat(agent): ingest dashboard databases via merged cycle + cache
This commit is contained in:
+36
-8
@@ -2,13 +2,16 @@
|
||||
|
||||
use crate::core::context::Context;
|
||||
use crate::services::backup::BackupService;
|
||||
use crate::services::config::ConfigService;
|
||||
use crate::services::config::{ConfigService, DatabaseConfig};
|
||||
use crate::services::cron::CronService;
|
||||
use crate::services::dashboard_config::{collect_configs, load_cache, merge, persist_cache};
|
||||
use crate::services::restore::RestoreService;
|
||||
use crate::services::status::StatusService;
|
||||
use crate::settings::CONFIG;
|
||||
use crate::utils::common::BackupMethod;
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tracing::info;
|
||||
use tracing::{error, info, warn};
|
||||
|
||||
pub struct Agent {
|
||||
ctx: Arc<Context>,
|
||||
@@ -17,6 +20,8 @@ pub struct Agent {
|
||||
cron_service: CronService,
|
||||
backup_service: BackupService,
|
||||
restore_service: RestoreService,
|
||||
dashboard_cache: Vec<DatabaseConfig>,
|
||||
cache_path: PathBuf,
|
||||
}
|
||||
|
||||
impl Agent {
|
||||
@@ -28,6 +33,9 @@ impl Agent {
|
||||
let backup_service = BackupService::new(ctx.clone());
|
||||
let restore_service = RestoreService::new(ctx.clone());
|
||||
|
||||
let cache_path = PathBuf::from(&CONFIG.data_path).join("dashboard_databases.json");
|
||||
let dashboard_cache = load_cache(&cache_path);
|
||||
|
||||
Agent {
|
||||
ctx,
|
||||
config_service,
|
||||
@@ -35,19 +43,39 @@ impl Agent {
|
||||
cron_service,
|
||||
backup_service,
|
||||
restore_service,
|
||||
dashboard_cache,
|
||||
cache_path,
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn run(&mut self, method: BackupMethod) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let config = self.config_service.load(None)?;
|
||||
let ping_result = self.status_service.ping(&config.databases).await?;
|
||||
let local = self.config_service.load_optional(None);
|
||||
|
||||
// Ping the merged set (local ∪ dashboard cache from the previous cycle)
|
||||
// so the payload — and thus Ping Status — covers dashboard databases too.
|
||||
let merged_in = merge(&local.databases, &self.dashboard_cache);
|
||||
let ping_result = self.status_service.ping(&merged_in.databases).await?;
|
||||
|
||||
// Reconcile the authoritative dashboard set from this response
|
||||
// (full-state: additions, edits and deletions all self-apply) and persist it.
|
||||
self.dashboard_cache = collect_configs(&ping_result);
|
||||
if let Err(e) = persist_cache(&self.cache_path, &self.dashboard_cache) {
|
||||
error!("Failed to persist dashboard cache: {e}");
|
||||
}
|
||||
|
||||
// Rebuild the merged set including databases new in THIS response, so their
|
||||
// backup/restore actions can run in the same cycle.
|
||||
let merged = merge(&local.databases, &self.dashboard_cache);
|
||||
|
||||
for db in ping_result.databases.iter() {
|
||||
let database = config
|
||||
let Some(database) = merged
|
||||
.databases
|
||||
.iter()
|
||||
.find(|cfg_db| cfg_db.generated_id == db.generated_id)
|
||||
.unwrap();
|
||||
else {
|
||||
warn!("No config for returned database {}; skipping", db.generated_id);
|
||||
continue;
|
||||
};
|
||||
info!(
|
||||
"Generated Id: {} | backup action: {} | restore action: {} | Database Name: {}",
|
||||
db.generated_id, db.data.backup.action, db.data.restore.action, database.name,
|
||||
@@ -59,14 +87,14 @@ impl Agent {
|
||||
.backup_service
|
||||
.dispatch(
|
||||
&db.generated_id,
|
||||
&config,
|
||||
&merged,
|
||||
method.clone(),
|
||||
&db.storages,
|
||||
db.encrypt,
|
||||
)
|
||||
.await;
|
||||
} else if db.data.restore.action {
|
||||
let _ = self.restore_service.dispatch(db, &config).await;
|
||||
let _ = self.restore_service.dispatch(db, &merged).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user