common/peer/sync/mod.rs
1//! Sync provider abstraction and job execution
2//!
3//! This module defines the sync provider trait and job types. Each job type
4//! has its own module with execution logic that can be reused by peers.
5
6use anyhow::Result;
7use async_trait::async_trait;
8
9use crate::bucket_log::BucketLogProvider;
10
11pub mod download_pins;
12pub mod ping_peer;
13pub mod sync_bucket;
14
15// Re-export job types and helpers
16pub use download_pins::DownloadPinsJob;
17pub use ping_peer::PingPeerJob;
18pub use sync_bucket::{SyncBucketJob, SyncTarget};
19
20/// Background sync job types
21///
22/// These represent the different kinds of background work that can be dispatched.
23#[derive(Debug, Clone)]
24pub enum SyncJob {
25 /// Sync a bucket from a remote peer
26 SyncBucket(SyncBucketJob),
27 /// Download pins from remote peers
28 DownloadPins(DownloadPinsJob),
29 /// Ping a peer to check bucket sync status
30 PingPeer(PingPeerJob),
31}
32
33/// Execute a sync job by calling the appropriate module's execute function
34///
35/// This is a helper function that dispatches to the per-job-type execution logic.
36/// Both synchronous and queued providers can use this.
37pub async fn execute_job<L>(peer: &crate::peer::Peer<L>, job: SyncJob) -> Result<()>
38where
39 L: BucketLogProvider + Clone + Send + Sync + 'static,
40 L::Error: std::error::Error + Send + Sync + 'static,
41{
42 match job {
43 SyncJob::DownloadPins(job) => download_pins::execute(peer, job).await,
44 SyncJob::SyncBucket(job) => sync_bucket::execute(peer, job).await,
45 SyncJob::PingPeer(job) => ping_peer::execute(peer, job).await,
46 }
47}
48
49/// Trait for sync provider implementations
50///
51/// This trait abstracts WHEN and WHERE sync jobs are executed. The actual sync
52/// logic lives in the per-job modules. Implementations decide the execution
53/// context:
54///
55/// - **Synchronous**: Execute immediately by calling execute_job directly
56/// - **Queued**: Send to a channel for background worker processing
57/// - **Actor-based**: Send to an actor mailbox for processing
58///
59/// This allows minimal peers to use simple synchronous execution, while complex
60/// applications can decouple sync jobs from protocol handlers using queues.
61#[async_trait]
62pub trait SyncProvider<L>: Send + Sync + std::fmt::Debug
63where
64 L: BucketLogProvider + Clone + Send + Sync + 'static,
65 L::Error: std::error::Error + Send + Sync + 'static,
66{
67 /// Execute a sync job with the given peer
68 ///
69 /// Implementations decide when and where this runs. The job execution logic
70 /// is provided by the execute_job helper and per-job modules.
71 async fn execute(&self, peer: &crate::peer::Peer<L>, job: SyncJob) -> Result<()>;
72}