use std::sync::Arc;
use tokio::{
sync::{broadcast::Receiver, RwLock},
task::JoinHandle,
};
use zenoh::{key_expr::OwnedKeyExpr, session::Session};
use super::{core::Replication, LogLatest};
use crate::storages_mgt::{LatestUpdates, StorageMessage, StorageService};
pub(crate) struct ReplicationService {
digest_publisher_handle: JoinHandle<()>,
digest_subscriber_handle: JoinHandle<()>,
aligner_queryable_handle: JoinHandle<()>,
}
impl ReplicationService {
pub async fn spawn_start(
zenoh_session: Arc<Session>,
storage_service: Arc<StorageService>,
storage_key_expr: OwnedKeyExpr,
replication_log: Arc<RwLock<LogLatest>>,
latest_updates: Arc<RwLock<LatestUpdates>>,
mut rx: Receiver<StorageMessage>,
) {
let replication = Replication {
zenoh_session,
replication_log,
storage_key_expr,
latest_updates,
storage_service,
};
if replication
.replication_log
.read()
.await
.intervals
.is_empty()
{
replication.initial_alignment().await;
}
tokio::task::spawn(async move {
let replication_service = Self {
digest_publisher_handle: replication.spawn_digest_publisher(),
digest_subscriber_handle: replication.spawn_digest_subscriber(),
aligner_queryable_handle: replication.spawn_aligner_queryable(),
};
while let Ok(storage_message) = rx.recv().await {
if matches!(storage_message, StorageMessage::Stop) {
replication_service.stop();
return;
}
}
});
}
pub fn stop(self) {
self.digest_publisher_handle.abort();
self.digest_subscriber_handle.abort();
self.aligner_queryable_handle.abort();
}
}