Disable sequential sync and store new file in v2 sync store

This commit is contained in:
boqiu 2024-10-24 15:30:07 +08:00
parent 98ec24b863
commit ceb165d79b
4 changed files with 62 additions and 39 deletions

View File

@ -59,14 +59,13 @@ impl RandomBatcher {
pub async fn start(mut self, catched_up: Arc<AtomicBool>) { pub async fn start(mut self, catched_up: Arc<AtomicBool>) {
info!("Start to sync files"); info!("Start to sync files");
loop { // wait for log entry sync catched up
// disable file sync until catched up while !catched_up.load(Ordering::Relaxed) {
if !catched_up.load(Ordering::Relaxed) {
trace!("Cannot sync file in catch-up phase"); trace!("Cannot sync file in catch-up phase");
sleep(self.config.auto_sync_idle_interval).await; sleep(self.config.auto_sync_idle_interval).await;
continue;
} }
loop {
if let Ok(state) = self.get_state().await { if let Ok(state) = self.get_state().await {
metrics::RANDOM_STATE_TXS_SYNCING.update(state.tasks.len() as u64); metrics::RANDOM_STATE_TXS_SYNCING.update(state.tasks.len() as u64);
metrics::RANDOM_STATE_TXS_READY.update(state.ready_txs as u64); metrics::RANDOM_STATE_TXS_READY.update(state.ready_txs as u64);

View File

@ -9,7 +9,7 @@ use storage_async::Store;
use task_executor::TaskExecutor; use task_executor::TaskExecutor;
use tokio::sync::{ use tokio::sync::{
broadcast, broadcast,
mpsc::{unbounded_channel, UnboundedSender}, mpsc::{unbounded_channel, UnboundedReceiver, UnboundedSender},
oneshot, oneshot,
}; };
@ -22,7 +22,7 @@ use super::{
}; };
pub struct AutoSyncManager { pub struct AutoSyncManager {
pub serial: SerialBatcher, pub serial: Option<SerialBatcher>,
pub random: RandomBatcher, pub random: RandomBatcher,
pub file_announcement_send: UnboundedSender<u64>, pub file_announcement_send: UnboundedSender<u64>,
pub new_file_send: UnboundedSender<u64>, pub new_file_send: UnboundedSender<u64>,
@ -35,60 +35,73 @@ impl AutoSyncManager {
executor: &TaskExecutor, executor: &TaskExecutor,
store: Store, store: Store,
sync_send: SyncSender, sync_send: SyncSender,
log_sync_recv: broadcast::Receiver<LogSyncEvent>, _log_sync_recv: broadcast::Receiver<LogSyncEvent>,
catch_up_end_recv: oneshot::Receiver<()>, catch_up_end_recv: oneshot::Receiver<()>,
) -> Result<Self> { ) -> Result<Self> {
let (file_announcement_send, file_announcement_recv) = unbounded_channel(); let (file_announcement_send, _file_announcement_recv) = unbounded_channel();
let (new_file_send, mut new_file_recv) = unbounded_channel(); let (new_file_send, new_file_recv) = unbounded_channel();
let sync_store = Arc::new(SyncStore::new(store.clone())); // use v2 db to avoid reading v1 files that announced from the whole network instead of neighbors
let sync_store = Arc::new(SyncStore::new_with_name(
store.clone(),
"pendingv2",
"readyv2",
));
let catched_up = Arc::new(AtomicBool::new(false)); let catched_up = Arc::new(AtomicBool::new(false));
// handle new file // handle new file
let sync_store_cloned = sync_store.clone();
executor.spawn( executor.spawn(
async move { Self::handle_new_file(new_file_recv, sync_store.clone()),
while let Some(tx_seq) = new_file_recv.recv().await {
if let Err(err) = sync_store_cloned.insert(tx_seq, Queue::Ready).await {
warn!(?err, %tx_seq, "Failed to insert new file to ready queue");
}
}
},
"auto_sync_handle_new_file", "auto_sync_handle_new_file",
); );
// sync in sequence // sync in sequence
let serial = // let serial =
SerialBatcher::new(config, store.clone(), sync_send.clone(), sync_store.clone()) // SerialBatcher::new(config, store.clone(), sync_send.clone(), sync_store.clone())
.await?; // .await?;
executor.spawn( // executor.spawn(
serial // serial
.clone() // .clone()
.start(file_announcement_recv, log_sync_recv, catched_up.clone()), // .start(file_announcement_recv, log_sync_recv, catched_up.clone()),
"auto_sync_serial", // "auto_sync_serial",
); // );
// sync randomly // sync randomly
let random = RandomBatcher::new(config, store, sync_send, sync_store); let random = RandomBatcher::new(config, store, sync_send, sync_store);
executor.spawn(random.clone().start(catched_up.clone()), "auto_sync_random"); executor.spawn(random.clone().start(catched_up.clone()), "auto_sync_random");
// handle on catched up notification // handle on catched up notification
let catched_up_cloned = catched_up.clone();
executor.spawn( executor.spawn(
async move { Self::listen_catch_up(catch_up_end_recv, catched_up.clone()),
if catch_up_end_recv.await.is_ok() {
info!("log entry catched up");
catched_up_cloned.store(true, Ordering::Relaxed);
}
},
"auto_sync_wait_for_catchup", "auto_sync_wait_for_catchup",
); );
Ok(Self { Ok(Self {
serial, serial: None,
random, random,
file_announcement_send, file_announcement_send,
new_file_send, new_file_send,
catched_up, catched_up,
}) })
} }
async fn handle_new_file(
mut new_file_recv: UnboundedReceiver<u64>,
sync_store: Arc<SyncStore>,
) {
while let Some(tx_seq) = new_file_recv.recv().await {
if let Err(err) = sync_store.insert(tx_seq, Queue::Ready).await {
warn!(?err, %tx_seq, "Failed to insert new file to ready queue");
}
}
}
async fn listen_catch_up(
catch_up_end_recv: oneshot::Receiver<()>,
catched_up: Arc<AtomicBool>,
) {
if catch_up_end_recv.await.is_ok() {
info!("log entry catched up");
catched_up.store(true, Ordering::Relaxed);
}
}
} }

View File

@ -42,6 +42,14 @@ impl SyncStore {
} }
} }
pub fn new_with_name(store: Store, pending: &'static str, ready: &'static str) -> Self {
Self {
store: Arc::new(RwLock::new(store)),
pending_txs: TxStore::new(pending),
ready_txs: TxStore::new(ready),
}
}
/// Returns the number of pending txs and ready txs. /// Returns the number of pending txs and ready txs.
pub async fn stat(&self) -> Result<(usize, usize)> { pub async fn stat(&self) -> Result<(usize, usize)> {
let async_store = self.store.read().await; let async_store = self.store.read().await;

View File

@ -284,7 +284,10 @@ impl SyncService {
Some(manager) => SyncServiceState { Some(manager) => SyncServiceState {
num_syncing: self.controllers.len(), num_syncing: self.controllers.len(),
catched_up: Some(manager.catched_up.load(Ordering::Relaxed)), catched_up: Some(manager.catched_up.load(Ordering::Relaxed)),
auto_sync_serial: Some(manager.serial.get_state().await), auto_sync_serial: match &manager.serial {
Some(v) => Some(v.get_state().await),
None => None,
},
auto_sync_random: manager.random.get_state().await.ok(), auto_sync_random: manager.random.get_state().await.ok(),
}, },
None => SyncServiceState { None => SyncServiceState {