actionqueue_engine/lease/
acquire.rs1use actionqueue_core::ids::RunId;
10
11use crate::lease::model::{Lease, LeaseExpiry, LeaseOwner};
12
13#[derive(Debug, Clone, PartialEq, Eq)]
15#[must_use]
16pub enum AcquireResult {
17 Acquired(Lease),
19 AlreadyLeased,
21 WrongRunSlot {
24 requested_run_id: RunId,
26 existing_run_id: RunId,
28 },
29}
30
31pub fn acquire(
42 run_id: RunId,
43 owner: LeaseOwner,
44 expiry: LeaseExpiry,
45 current_lease: Option<Lease>,
46) -> AcquireResult {
47 match current_lease {
48 Some(existing) if existing.run_id() == run_id => AcquireResult::AlreadyLeased,
49 Some(existing) => AcquireResult::WrongRunSlot {
50 requested_run_id: run_id,
51 existing_run_id: existing.run_id(),
52 },
53 None => AcquireResult::Acquired(Lease::new(run_id, owner, expiry)),
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn acquire_succeeds_when_no_existing_lease() {
63 let run_id = RunId::new();
64 let owner = LeaseOwner::new("worker-1");
65 let expiry = LeaseExpiry::at(2000);
66
67 let result = acquire(run_id, owner, expiry, None);
68
69 match result {
70 AcquireResult::Acquired(lease) => {
71 assert_eq!(lease.run_id(), run_id);
72 assert_eq!(lease.owner().as_str(), "worker-1");
73 assert_eq!(lease.expiry().expires_at(), 2000);
74 }
75 AcquireResult::AlreadyLeased => panic!("Expected acquisition to succeed"),
76 AcquireResult::WrongRunSlot { .. } => {
77 panic!("Expected acquisition to use matching run slot")
78 }
79 }
80 }
81
82 #[test]
83 fn acquire_fails_when_lease_already_active() {
84 let run_id = RunId::new();
85 let existing_lease = Lease::new(run_id, "worker-1".into(), LeaseExpiry::at(2000));
86
87 let result =
88 acquire(run_id, "worker-2".into(), LeaseExpiry::at(3000), Some(existing_lease));
89
90 assert_eq!(result, AcquireResult::AlreadyLeased);
91 }
92
93 #[test]
94 fn acquire_returns_rejection_on_conflict() {
95 let run_id = RunId::new();
96 let existing_lease = Lease::new(run_id, "worker-1".into(), LeaseExpiry::at(2000));
97
98 let result =
99 acquire(run_id, "worker-2".into(), LeaseExpiry::at(3000), Some(existing_lease));
100
101 assert_eq!(result, AcquireResult::AlreadyLeased);
102 }
103
104 #[test]
105 fn acquire_reports_wrong_run_slot_when_existing_lease_is_for_different_run() {
106 let requested_run_id = RunId::new();
107 let existing_run_id = RunId::new();
108 let existing_lease = Lease::new(existing_run_id, "worker-1".into(), LeaseExpiry::at(2000));
109
110 let result = acquire(
111 requested_run_id,
112 "worker-2".into(),
113 LeaseExpiry::at(3000),
114 Some(existing_lease),
115 );
116
117 assert_eq!(result, AcquireResult::WrongRunSlot { requested_run_id, existing_run_id });
118 }
119}