ledgence_orchestration_api/
lib.rs1pub use ledgence_worker_api::TraceContext;
12
13mod acquisition;
14mod completion;
15mod delivery;
16mod discovery;
17mod dispatch;
18mod observation;
19mod retention;
20mod storage;
21mod submission;
22mod workflow;
23mod workflow_children;
24mod workflow_events;
25pub use acquisition::*;
26pub use completion::*;
27pub use delivery::*;
28pub use discovery::*;
29pub use dispatch::*;
30pub use observation::*;
31pub use retention::*;
32pub use storage::*;
33pub use submission::*;
34pub use workflow::*;
35pub use workflow_children::*;
36pub use workflow_events::*;
37
38use ledgence_worker_api::{Error, ErrorKind};
39use serde::{Deserialize, Serialize};
40use std::{fmt, future::Future, pin::Pin};
41
42#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
45#[serde(tag = "code", content = "message", rename_all = "snake_case")]
46pub enum ContractError {
47 InvalidInput(String),
48 ExternalDispatchRequired,
54 InvalidQueueDelivery(String),
59 Conflict,
60 OwnershipLost,
61 UnknownSession,
62 SessionExpired,
63 ObsoleteOperation,
64 OutOfOrder,
65 Busy,
66 NotFound,
67 Unavailable(String),
68}
69impl From<Error> for ContractError {
70 fn from(error: Error) -> Self {
71 Self::InvalidInput(error.to_string())
72 }
73}
74impl fmt::Display for ContractError {
75 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76 write!(f, "{self:?}")
77 }
78}
79impl std::error::Error for ContractError {}
80pub type Result<T> = std::result::Result<T, ContractError>;
81pub type ContractFuture<'a, T> = Pin<Box<dyn Future<Output = Result<T>> + Send + 'a>>;
82
83#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
85#[serde(deny_unknown_fields)]
86pub struct RetryPolicy {
87 pub max_attempts: u32,
88 pub retry_delay_ms: u64,
89}
90impl Default for RetryPolicy {
91 fn default() -> Self {
92 Self {
93 max_attempts: 3,
94 retry_delay_ms: 5_000,
95 }
96 }
97}
98impl RetryPolicy {
99 pub fn validate(&self) -> ledgence_worker_api::Result<()> {
100 if !(1..=1_000).contains(&self.max_attempts) || self.retry_delay_ms > 86_400_000 {
101 return Err(Error::new(
102 ErrorKind::InvalidInput,
103 "retry policy exceeds supported limits",
104 ));
105 }
106 Ok(())
107 }
108}
109
110pub const LEASE_DURATION_MS: u64 = 60_000;
112pub const RENEW_INTERVAL_MS: u64 = 15_000;
113pub const LEASE_SAFETY_MARGIN_MS: u64 = 5_000;
114pub const LONG_POLL_WAIT_MS: u64 = 20_000;
115pub const CONTROL_REQUEST_TIMEOUT_MS: u64 = 30_000;
116pub const CLEANUP_GRACE_MS: u64 = 30_000;
117pub const SESSION_VALIDITY_MS: u64 = 86_400_000;
118pub const TERMINAL_RETENTION_MS: u64 = 90 * 86_400_000;
119pub const SETTLEMENT_MAX_BYTES: usize = 8 * 1024 * 1024;
120
121pub fn validate_text(value: &str, maximum: usize) -> Result<()> {
123 if value.is_empty()
124 || value.len() > maximum
125 || value.chars().any(|character| {
126 let code = u32::from(character);
127 character.is_control() || (0xfdd0..=0xfdef).contains(&code) || (code & 0xfffe) == 0xfffe
128 })
129 {
130 return Err(ContractError::InvalidInput(
131 "invalid platform identifier/reference".into(),
132 ));
133 }
134 Ok(())
135}