Skip to main content

photon_backend/
handler_descriptor.rs

1//! Handler descriptor for `#[photon::subscribe]` inventory registration.
2
3use std::future::Future;
4use std::pin::Pin;
5
6use photon_core::IdentityFactory;
7
8use crate::error::Result;
9use crate::models::Event;
10
11/// Invokes a registered handler with reconstructed identity and the transport event.
12///
13/// The generated invoker reads `actor_json` / `payload_json` (and metadata) from `event`.
14pub type HandlerInvoker = for<'a> fn(
15    &'a dyn IdentityFactory,
16    &'a Event,
17) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>>;
18
19/// Descriptor for a `#[photon::subscribe]` handler (inventory + executor dispatch).
20#[derive(Clone, Copy)]
21pub struct HandlerDescriptor {
22    /// Topic this handler listens on.
23    pub topic_name: &'static str,
24    /// Durable subscription name for broadcast handlers (empty for group handlers).
25    pub subscription_name: &'static str,
26    /// Stable registry key (`{topic}:{subscription}` or `{topic}:group:{group}`).
27    pub registry_key: &'static str,
28    /// Async dispatch entry point generated by the proc macro.
29    pub invoke: HandlerInvoker,
30    /// Consumer group id when load-balanced (mutually exclusive with durable name).
31    pub consumer_group: Option<&'static str>,
32    /// Override virtual shard count for group handlers.
33    pub group_shard_count: Option<u32>,
34}
35
36impl HandlerDescriptor {
37    /// Create a broadcast handler descriptor for inventory submission.
38    pub const fn new(
39        topic_name: &'static str,
40        subscription_name: &'static str,
41        registry_key: &'static str,
42        invoke: HandlerInvoker,
43    ) -> Self {
44        Self {
45            topic_name,
46            subscription_name,
47            registry_key,
48            invoke,
49            consumer_group: None,
50            group_shard_count: None,
51        }
52    }
53
54    /// Create a consumer-group handler descriptor.
55    pub const fn new_group(
56        topic_name: &'static str,
57        consumer_group: &'static str,
58        group_shard_count: Option<u32>,
59        registry_key: &'static str,
60        invoke: HandlerInvoker,
61    ) -> Self {
62        Self {
63            topic_name,
64            subscription_name: "",
65            registry_key,
66            invoke,
67            consumer_group: Some(consumer_group),
68            group_shard_count,
69        }
70    }
71
72    /// Whether this handler uses consumer-group delivery.
73    #[must_use]
74    pub const fn is_consumer_group(&self) -> bool {
75        self.consumer_group.is_some()
76    }
77}
78
79crate::inventory::collect!(HandlerDescriptor);
80
81impl quark::Registrable for HandlerDescriptor {
82    fn registry_key(&self) -> &str {
83        self.registry_key
84    }
85}