Skip to main content

photon_backend/
delivery_mode.rs

1//! Topic delivery mode and virtual shard configuration.
2
3/// How publishes on a topic are routed to subscribers.
4#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
5pub enum DeliveryMode {
6    /// Every matching subscriber receives every event (default).
7    #[default]
8    Broadcast,
9    /// Events routed to virtual shards; one consumer group member per shard.
10    ConsumerGroup,
11}
12
13impl std::str::FromStr for DeliveryMode {
14    type Err = ();
15
16    /// Parse `"broadcast"`, `"group"`, or `"consumer_group"`.
17    fn from_str(s: &str) -> Result<Self, Self::Err> {
18        match s {
19            "broadcast" => Ok(Self::Broadcast),
20            "group" | "consumer_group" => Ok(Self::ConsumerGroup),
21            _ => Err(()),
22        }
23    }
24}
25
26/// Virtual shard settings for [`DeliveryMode::ConsumerGroup`] topics.
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub struct ShardConfig {
29    /// Number of virtual shards (`hash(routing_key) % shard_count`).
30    pub shard_count: u32,
31    /// JSON payload field used for routing when publish has no explicit partition key.
32    pub shard_by: Option<&'static str>,
33}
34
35impl ShardConfig {
36    /// Default shard count when topic macro omits `shards`.
37    pub const DEFAULT_SHARD_COUNT: u32 = 32;
38
39    /// Create shard config; `0` count is replaced with [`Self::DEFAULT_SHARD_COUNT`].
40    #[must_use]
41    pub const fn new(shard_count: u32, shard_by: Option<&'static str>) -> Self {
42        Self {
43            shard_count: if shard_count == 0 {
44                Self::DEFAULT_SHARD_COUNT
45            } else {
46                shard_count
47            },
48            shard_by,
49        }
50    }
51
52    /// Default shard count with no `shard_by` field.
53    #[must_use]
54    pub const fn default_count() -> Self {
55        Self::new(Self::DEFAULT_SHARD_COUNT, None)
56    }
57}