use std::path::Path;
use std::sync::Arc;
use futures::stream::{FuturesUnordered, StreamExt};
use crate::database::sharding::ShardRouter;
#[derive(Debug, Clone)]
pub struct ShardMigrationResult {
pub shard_id: u32,
pub success: bool,
pub applied_versions: Vec<u32>,
pub error: Option<String>,
}
#[derive(Debug, Clone)]
pub struct OrchestratedMigrationResult {
pub total_shards: u32,
pub success_count: u32,
pub failed_shards: Vec<ShardMigrationResult>,
pub results: Vec<ShardMigrationResult>,
}
pub struct ShardMigrationOrchestrator {
router: Arc<ShardRouter>,
parallel: bool,
}
impl ShardMigrationOrchestrator {
pub fn new(router: Arc<ShardRouter>, parallel: bool) -> Self {
Self { router, parallel }
}
pub async fn orchestrate_migration(&self, _migrations_dir: &Path) -> OrchestratedMigrationResult {
let shards = self.router.all_shards();
let total_shards = shards.len() as u32;
if self.parallel {
self.orchestrate_parallel(shards, total_shards).await
} else {
self.orchestrate_serial(shards, total_shards).await
}
}
async fn orchestrate_parallel(
&self,
shards: Vec<&crate::database::sharding::ShardInfo>,
total_shards: u32,
) -> OrchestratedMigrationResult {
let mut futures = FuturesUnordered::new();
for shard_info in shards {
let shard_id = shard_info.shard_id;
futures.push(async move {
ShardMigrationResult {
shard_id,
success: true,
applied_versions: Vec::new(),
error: None,
}
});
}
let mut results = Vec::new();
while let Some(result) = futures.next().await {
results.push(result);
}
Self::summarize(total_shards, results)
}
async fn orchestrate_serial(
&self,
shards: Vec<&crate::database::sharding::ShardInfo>,
total_shards: u32,
) -> OrchestratedMigrationResult {
let mut results = Vec::new();
for shard_info in shards {
let shard_id = shard_info.shard_id;
results.push(ShardMigrationResult {
shard_id,
success: true,
applied_versions: Vec::new(),
error: None,
});
}
Self::summarize(total_shards, results)
}
fn summarize(total_shards: u32, results: Vec<ShardMigrationResult>) -> OrchestratedMigrationResult {
let success_count = results.iter().filter(|r| r.success).count() as u32;
let failed_shards: Vec<_> = results.iter().filter(|r| !r.success).cloned().collect();
OrchestratedMigrationResult {
total_shards,
success_count,
failed_shards,
results,
}
}
}