mod.rs

Overview

This file implements a service for synchronizing binary large objects (blobs) using external file shares. It provides functionality to share blobs and load blobs from external services while managing these operations asynchronously through an internal service loop. The service leverages an instrumented messaging channel for communication and supports metrics integration to monitor blob synchronization commands.

The main abstraction is the ServiceInterface which implements the BlobSyncService trait, exposing methods to share and load blobs. The service is started via the ExternalFileSharesBased struct, which encapsulates the base path for local storage of shared files.


Structs and Their Responsibilities

ExternalFileSharesBased

Service

ServiceInterface


BlobSyncService Trait Implementation

ServiceInterface implements the following methods:

share_blob

fn share_blob<Callback>(
    &mut self,
    resource_id: ResourceId,
    blob: impl Blob,
    on_complete: Callback,
) -> anyhow::Result<()>
where
    Callback: FnOnce(anyhow::Result<()>) + Send + Sync + 'static,

load_blob

fn load_blob<SuccessCallback, ErrorCallback>(
    &mut self,
    resource_id: ResourceId,
    known_external_blob_share_services: Vec<url::Url>,
    max_tries: u8,
    retry_download_timeout: Option<std::time::Duration>,
    deadline: Option<std::time::Instant>,
    on_success: SuccessCallback,
    on_error: ErrorCallback,
) -> anyhow::Result<()>
where
    SuccessCallback: FnOnce(&mut dyn std::io::Read) + Send + Sync + 'static,
    ErrorCallback: FnOnce(anyhow::Error) + Send + Sync + 'static,

Internal Command Loop

The service runs an internal thread (inner_loop) which receives commands via an instrumented channel. These commands are defined in the service_inner_loop module and include:

The inner loop handles these commands asynchronously, performing the actual file I/O and network operations necessary to share or download blobs. This design decouples the interface from the blocking operations and allows the service to process multiple commands efficiently.


Interaction with Other Modules


Important Implementation Details


Diagram: Service Structure and Interaction Flow

classDiagram
class ExternalFileSharesBased {
+local_storage_share_base_path: PathBuf
+start()
}
class Service {
+inner_loop: JoinHandle
+interface: ServiceInterface
+interface()
+join()
}
class ServiceInterface {
+control: InstrumentedSender
+share_blob()
+load_blob()
}
ExternalFileSharesBased --> Service : starts
Service --> ServiceInterface : provides interface
ServiceInterface ..> service_inner_loop::Command : sends commands

This diagram illustrates the relationships between the main structs: ExternalFileSharesBased starts the Service, which holds an internal thread and provides a ServiceInterface for command submission. The ServiceInterface sends commands to the internal loop defined in service_inner_loop.


Usage Workflow

  1. Initialization:
    Create an ExternalFileSharesBased instance with the local storage path and optional metrics.

  2. Service Start:
    Call .start() to launch the service thread and obtain a Service instance.

  3. Command Submission:
    Use the ServiceInterface obtained from Service.interface() to call:

    • share_blob for sharing blobs.

    • load_blob for loading blobs from external services.

  4. Service Shutdown:
    Call Service.join() to gracefully shut down the internal thread after dropping interfaces.


Related Topics