aura_core/effects/
time.rs1use crate::time::{OrderTime, PhysicalTime, TimeOrdering};
19use async_trait::async_trait;
20use serde::{Deserialize, Serialize};
21use uuid::Uuid;
22
23#[derive(Debug, thiserror::Error, Serialize, Deserialize)]
25pub enum TimeError {
26 #[error("Timeout after {timeout_ms}ms")]
27 Timeout { timeout_ms: u64 },
28 #[error("Timeout handle not found: {handle}")]
29 TimeoutNotFound { handle: TimeoutHandle },
30 #[error("Clock sync failed: {reason}")]
31 ClockSyncFailed { reason: String },
32 #[error("Time service unavailable")]
33 ServiceUnavailable,
34 #[error("Operation failed: {reason}")]
35 OperationFailed { reason: String },
36}
37
38pub type TimeoutHandle = Uuid;
40
41#[derive(Debug, Clone)]
43pub enum WakeCondition {
44 Immediate,
45 NewEvents,
46 EpochReached { target: u64 },
47 TimeoutAt(u64),
48 TimeoutExpired { timeout_id: TimeoutHandle },
49 EventMatching(String),
50 ThresholdEvents { threshold: u32, timeout_ms: u64 },
51 Custom(String),
52}
53
54#[async_trait]
55pub trait PhysicalTimeEffects: Send + Sync {
56 async fn physical_time(&self) -> Result<PhysicalTime, TimeError>;
57 async fn sleep_ms(&self, ms: u64) -> Result<(), TimeError>;
58}
59
60#[async_trait]
61pub trait LogicalClockEffects: Send + Sync {
62 async fn logical_advance(
63 &self,
64 observed: Option<&crate::time::VectorClock>,
65 ) -> Result<crate::time::LogicalTime, TimeError>;
66 async fn logical_now(&self) -> Result<crate::time::LogicalTime, TimeError>;
67}
68
69#[async_trait]
70pub trait OrderClockEffects: Send + Sync {
71 async fn order_time(&self) -> Result<OrderTime, TimeError>;
72}
73
74#[async_trait]
75pub trait TimeComparison: Send + Sync {
76 async fn compare(
77 &self,
78 a: &crate::time::TimeStamp,
79 b: &crate::time::TimeStamp,
80 ) -> Result<TimeOrdering, TimeError>;
81}
82
83#[async_trait]
89pub trait TimeEffects: PhysicalTimeEffects {
90 async fn current_timestamp(&self) -> u64 {
92 self.physical_time()
93 .await
94 .map(|t| t.ts_ms / 1000)
95 .unwrap_or(0)
96 }
97
98 async fn current_timestamp_ms(&self) -> u64 {
100 self.physical_time().await.map(|t| t.ts_ms).unwrap_or(0)
101 }
102
103 async fn current_epoch(&self) -> u64 {
105 self.current_timestamp().await
106 }
107}
108
109#[async_trait]
111impl<T: PhysicalTimeEffects + ?Sized> PhysicalTimeEffects for std::sync::Arc<T> {
112 async fn physical_time(&self) -> Result<PhysicalTime, TimeError> {
113 (**self).physical_time().await
114 }
115
116 async fn sleep_ms(&self, ms: u64) -> Result<(), TimeError> {
117 (**self).sleep_ms(ms).await
118 }
119}
120
121#[async_trait]
123impl<T: LogicalClockEffects + ?Sized> LogicalClockEffects for std::sync::Arc<T> {
124 async fn logical_advance(
125 &self,
126 observed: Option<&crate::time::VectorClock>,
127 ) -> Result<crate::time::LogicalTime, TimeError> {
128 (**self).logical_advance(observed).await
129 }
130
131 async fn logical_now(&self) -> Result<crate::time::LogicalTime, TimeError> {
132 (**self).logical_now().await
133 }
134}
135
136#[async_trait]
138impl<T: OrderClockEffects + ?Sized> OrderClockEffects for std::sync::Arc<T> {
139 async fn order_time(&self) -> Result<OrderTime, TimeError> {
140 (**self).order_time().await
141 }
142}
143
144#[async_trait]
146impl<T: TimeComparison + ?Sized> TimeComparison for std::sync::Arc<T> {
147 async fn compare(
148 &self,
149 a: &crate::time::TimeStamp,
150 b: &crate::time::TimeStamp,
151 ) -> Result<TimeOrdering, TimeError> {
152 (**self).compare(a, b).await
153 }
154}