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:
| Adapter | Type | Crate |
|---|---|---|
| In-process | InProcStoragePort | photon-backend (mem) |
SQLite | SqliteStoragePort | photon-backend-sqlite |
NATS JetStream | NatsStoragePort | photon-backend-nats |
| Kafka | KafkaStoragePort | photon-backend-kafka |
| Fluvio | FluvioStoragePort | photon-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§
Sourcefn capabilities(&self) -> StorageCapabilities
fn capabilities(&self) -> StorageCapabilities
Adapter capabilities for contract tests and telemetry.
Sourcefn 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 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,
Sourcefn subscribe(
&self,
topic_name: String,
topic_key_filter: Option<String>,
after_seq: Option<i64>,
) -> Pin<Box<dyn Stream<Item = Result<Event, PhotonError>> + Send>>
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_seqis set, only events withseq > after_seqare yielded. - When
topic_key_filteris set, only matching partition keys are delivered. - The stream runs until dropped or an error; live adapters may block for new events.
Sourcefn 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 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
Nonewhen the id is unknown or the event was truncated by retention.
Sourcefn 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 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
Nonewhen no checkpoint exists (caller chooses replay start policy).
Sourcefn 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,
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_seqis monotonic per subscription partition; adapters may reject regressions.
Provided Methods§
Sourcefn 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 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.
Sourcefn 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,
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".