1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
5pub enum SemanticBehavior {
6 AtLeastOnceExecution,
7 RunAtEligibility,
8 LeaseExclusivity,
9 CrashRecoveryAfterLeaseExpiry,
10 MonotonicConsumerGroupOffsets,
11 SafeStreamPruning,
12 Durability,
13 TransactionalEnqueue,
14 DistributedWorkers,
15 NotificationDelivery,
16 WakeUpLatency,
17 Backpressure,
18 StreamRetention,
19 ExactlyOnceExecution,
20 ExactlyOnceExternalSideEffects,
21 ExactRunAtExecution,
22 CompletionOrdering,
23 GlobalOrdering,
24 WorkerFairness,
25 ArbitraryExternalTransactions,
26 PermanentRetention,
27 AutomaticScaling,
28 ConsumerGroupWorkBalancing,
29}
30
31impl SemanticBehavior {
32 pub const ALL: [Self; 23] = [
34 Self::AtLeastOnceExecution,
35 Self::RunAtEligibility,
36 Self::LeaseExclusivity,
37 Self::CrashRecoveryAfterLeaseExpiry,
38 Self::MonotonicConsumerGroupOffsets,
39 Self::SafeStreamPruning,
40 Self::Durability,
41 Self::TransactionalEnqueue,
42 Self::DistributedWorkers,
43 Self::NotificationDelivery,
44 Self::WakeUpLatency,
45 Self::Backpressure,
46 Self::StreamRetention,
47 Self::ExactlyOnceExecution,
48 Self::ExactlyOnceExternalSideEffects,
49 Self::ExactRunAtExecution,
50 Self::CompletionOrdering,
51 Self::GlobalOrdering,
52 Self::WorkerFairness,
53 Self::ArbitraryExternalTransactions,
54 Self::PermanentRetention,
55 Self::AutomaticScaling,
56 Self::ConsumerGroupWorkBalancing,
57 ];
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
62pub enum SemanticClassification {
63 Guaranteed,
64 BackendDependent,
65 Unspecified,
66}
67
68#[derive(Debug, Clone, Copy, PartialEq, Eq)]
70pub struct SemanticContract {
71 pub behavior: SemanticBehavior,
72 pub classification: SemanticClassification,
73 pub contract: &'static str,
74 pub supported_alternative: Option<&'static str>,
75}
76
77pub const fn semantic_contract(behavior: SemanticBehavior) -> SemanticContract {
79 use SemanticBehavior::*;
80 use SemanticClassification::*;
81
82 let (classification, contract, supported_alternative) = match behavior {
83 AtLeastOnceExecution => (Guaranteed, "A committed runnable job may execute more than once but is not silently discarded.", None),
84 RunAtEligibility => (Guaranteed, "A scheduled job is not eligible for leasing before its backend clock reaches run_at.", None),
85 LeaseExclusivity => (Guaranteed, "A job has at most one unexpired worker lease at a time.", None),
86 CrashRecoveryAfterLeaseExpiry => (Guaranteed, "Abandoned work becomes runnable after lease expiry and recovery.", None),
87 MonotonicConsumerGroupOffsets => (Guaranteed, "Acknowledgement never moves a consumer-group offset backward.", None),
88 SafeStreamPruning => (Guaranteed, "Explicit pruning does not pass the lowest known consumer-group offset.", None),
89 Durability => (BackendDependent, "Persistence strength is declared by StorageBackend::semantic_capabilities().durability.", None),
90 TransactionalEnqueue => (BackendDependent, "Atomicity scope is declared by StorageBackend::semantic_capabilities().transactional_enqueue_scope.", None),
91 DistributedWorkers => (BackendDependent, "Multi-process lease coordination requires distributed_workers = true.", None),
92 NotificationDelivery => (BackendDependent, "Notifications are hints with behavior declared by StorageBackend::semantic_capabilities().notification_delivery.", Some("Read or lease durable backend state after every wake-up and on a polling fallback.")),
93 WakeUpLatency => (BackendDependent, "Azums provides no backend-independent notification latency bound.", Some("Configure worker polling and measure queue claim latency.")),
94 Backpressure => (BackendDependent, "Overload behavior is declared by BackendCapabilities::backpressure.", None),
95 StreamRetention => (BackendDependent, "Retention is declared by StorageBackend::semantic_capabilities().stream_retention and backend configuration.", None),
96 ExactlyOnceExecution => (Unspecified, "Handlers may execute more than once after retries, crashes, lease expiry, or replay.", Some("Use idempotent handlers and an application deduplication record.")),
97 ExactlyOnceExternalSideEffects => (Unspecified, "Azums cannot atomically control arbitrary external side effects.", Some("Use provider idempotency keys or a transactional outbox in the same database.")),
98 ExactRunAtExecution => (Unspecified, "run_at is an eligibility boundary, not an exact execution timestamp.", Some("Use deadline_at for a latest-start bound and observe scheduling latency.")),
99 CompletionOrdering => (Unspecified, "Parallel workers may complete jobs in any order.", Some("Use one worker with batch size one when serial completion is required.")),
100 GlobalOrdering => (Unspecified, "Azums defines no total order across queues or streams.", Some("Route related work through one FIFO queue or one stream.")),
101 WorkerFairness => (Unspecified, "Azums does not guarantee equal or fair work distribution among workers.", Some("Observe worker throughput and enforce deployment-level limits.")),
102 ArbitraryExternalTransactions => (Unspecified, "Azums does not provide atomic transactions across unrelated services.", Some("Use same-database enqueue, an outbox, or an application saga.")),
103 PermanentRetention => (Unspecified, "No backend can promise retention independent of operator deletion, media loss, or configuration.", Some("Use backups, replication, archival, and explicit retention policy.")),
104 AutomaticScaling => (Unspecified, "Azums does not provision or remove worker processes.", Some("Scale from exported queue-depth and latency metrics.")),
105 ConsumerGroupWorkBalancing => (Unspecified, "Consumer groups persist offsets but do not assign events to members.", Some("Add application-owned partition assignment or use distinct groups.")),
106 };
107
108 SemanticContract {
109 behavior,
110 classification,
111 contract,
112 supported_alternative,
113 }
114}