Skip to main content

StoragePort

Trait StoragePort 

Source
pub trait StoragePort: Send + Sync {
    // Required methods
    fn capabilities(&self) -> StorageCapabilities;
    fn append<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        topic_name: &'life1 str,
        topic_key: Option<&'life2 str>,
        actor_json: Value,
        payload_json: Value,
    ) -> Pin<Box<dyn Future<Output = Result<Event, PhotonError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             Self: 'async_trait;
    fn subscribe(
        &self,
        topic_name: String,
        topic_key_filter: Option<String>,
        after_seq: Option<i64>,
    ) -> Pin<Box<dyn Stream<Item = Result<Event, PhotonError>> + Send>>;
    fn get_event<'life0, 'life1, 'async_trait>(
        &'life0 self,
        event_id: &'life1 str,
    ) -> Pin<Box<dyn Future<Output = Result<Option<Event>, PhotonError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             Self: 'async_trait;
    fn load_checkpoint<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        subscription_name: &'life1 str,
        topic_name: &'life2 str,
        topic_key: Option<&'life3 str>,
    ) -> Pin<Box<dyn Future<Output = Result<Option<i64>, PhotonError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             Self: 'async_trait;
    fn commit_checkpoint<'life0, 'life1, 'life2, 'life3, 'async_trait>(
        &'life0 self,
        subscription_name: &'life1 str,
        topic_name: &'life2 str,
        topic_key: Option<&'life3 str>,
        last_seq: i64,
    ) -> Pin<Box<dyn Future<Output = Result<(), PhotonError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             'life3: 'async_trait,
             Self: 'async_trait;

    // Provided methods
    fn truncate_before<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        topic_name: &'life1 str,
        topic_key: Option<&'life2 str>,
        truncate_bound: i64,
    ) -> Pin<Box<dyn Future<Output = Result<u64, PhotonError>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             Self: 'async_trait { ... }
    fn delivery_seq_pin<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        topic_name: &'life1 str,
        topic_key: Option<&'life2 str>,
    ) -> Pin<Box<dyn Future<Output = Option<i64>> + Send + 'async_trait>>
       where 'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait,
             Self: 'async_trait { ... }
}
Expand description

Storage adapter contract — append, subscribe, checkpoints, and optional retention.

Each method documents its behavior under Contract. Built-in implementations:

AdapterTypeCrate
In-processInProcStoragePortphoton-backend (mem)
SQLiteSqliteStoragePortphoton-backend-sqlite
NATS JetStreamNatsStoragePortphoton-backend-nats
KafkaKafkaStoragePortphoton-backend-kafka
FluvioFluvioStoragePortphoton-backend-fluvio

§Example (use a built-in port)

use std::sync::Arc;

use photon_backend::{InProcStoragePort, StoragePort, TransportCrypto};

let port: Arc<dyn StoragePort> = Arc::new(InProcStoragePort::new(
    TransportCrypto::from_env()?,
));
let _caps = port.capabilities();

Install at boot via the facade PhotonBuilder. Host walkthrough: Integrating the host.

Required Methods§

Source

fn capabilities(&self) -> StorageCapabilities

Adapter capabilities for contract tests and telemetry.

Source

fn append<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, topic_name: &'life1 str, topic_key: Option<&'life2 str>, actor_json: Value, payload_json: Value, ) -> Pin<Box<dyn Future<Output = Result<Event, PhotonError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Append one event to a topic partition.

§Contract
  • Assigns a monotonically increasing seq per (topic_name, topic_key) partition.
  • Returns the persisted Event including stable event_id.
  • Payload and actor JSON are opaque to the adapter (encryption happens above the port).
Source

fn subscribe( &self, topic_name: String, topic_key_filter: Option<String>, after_seq: Option<i64>, ) -> Pin<Box<dyn Stream<Item = Result<Event, PhotonError>> + Send>>

Stream events for a topic partition, optionally replaying after after_seq.

§Contract
  • When after_seq is set, only events with seq > after_seq are yielded.
  • When topic_key_filter is set, only matching partition keys are delivered.
  • The stream runs until dropped or an error; live adapters may block for new events.
Source

fn get_event<'life0, 'life1, 'async_trait>( &'life0 self, event_id: &'life1 str, ) -> Pin<Box<dyn Future<Output = Result<Option<Event>, PhotonError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, Self: 'async_trait,

Point lookup by event id (optional — see StorageCapabilities::supports_get_event).

§Contract
  • Returns None when the id is unknown or the event was truncated by retention.
Source

fn load_checkpoint<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, subscription_name: &'life1 str, topic_name: &'life2 str, topic_key: Option<&'life3 str>, ) -> Pin<Box<dyn Future<Output = Result<Option<i64>, PhotonError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, Self: 'async_trait,

Load durable subscription high-water seq.

§Contract
  • Returns None when no checkpoint exists (caller chooses replay start policy).
Source

fn commit_checkpoint<'life0, 'life1, 'life2, 'life3, 'async_trait>( &'life0 self, subscription_name: &'life1 str, topic_name: &'life2 str, topic_key: Option<&'life3 str>, last_seq: i64, ) -> Pin<Box<dyn Future<Output = Result<(), PhotonError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, 'life3: 'async_trait, Self: 'async_trait,

Persist durable subscription high-water seq.

§Contract
  • last_seq is monotonic per subscription partition; adapters may reject regressions.

Provided Methods§

Source

fn truncate_before<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, topic_name: &'life1 str, topic_key: Option<&'life2 str>, truncate_bound: i64, ) -> Pin<Box<dyn Future<Output = Result<u64, PhotonError>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Trim events before truncate_bound for a partition (no-op when unsupported).

§Contract
  • Default implementation returns Ok(0) without removing events.
  • Supporting adapters remove events with seq < truncate_bound.
Source

fn delivery_seq_pin<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, topic_name: &'life1 str, topic_key: Option<&'life2 str>, ) -> Pin<Box<dyn Future<Output = Option<i64>> + Send + 'async_trait>>
where 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait, Self: 'async_trait,

Last delivered seq pin for retention watermarks (optional).

§Contract
  • Default returns None (no delivery-layer retention pin).

Dyn Compatibility§

This trait is dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§