ralph/session/
validation.rs1use std::path::Path;
16
17use crate::contracts::{QueueFile, SessionState, TaskStatus};
18use crate::timeutil;
19
20use super::persistence::load_session;
21
22#[allow(clippy::large_enum_variant)]
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub enum SessionValidationResult {
25 Valid(SessionState),
26 NoSession,
27 Stale { reason: String },
28 Timeout { hours: u64, session: SessionState },
29}
30
31pub fn validate_session_with_now(
32 session: &SessionState,
33 queue: &QueueFile,
34 timeout_hours: Option<u64>,
35 now: time::OffsetDateTime,
36) -> SessionValidationResult {
37 let task = match queue
38 .tasks
39 .iter()
40 .find(|task| task.id.trim() == session.task_id)
41 {
42 Some(task) => task,
43 None => {
44 return SessionValidationResult::Stale {
45 reason: format!("Task {} no longer exists in queue", session.task_id),
46 };
47 }
48 };
49
50 if task.status != TaskStatus::Doing {
51 return SessionValidationResult::Stale {
52 reason: format!(
53 "Task {} is not in Doing status (current: {})",
54 session.task_id, task.status
55 ),
56 };
57 }
58
59 if let Some(timeout) = timeout_hours
60 && let Ok(session_time) = timeutil::parse_rfc3339(&session.last_updated_at)
61 && now > session_time
62 {
63 let elapsed = now - session_time;
64 let hours = elapsed.whole_hours() as u64;
65 if hours >= timeout {
66 return SessionValidationResult::Timeout {
67 hours,
68 session: session.clone(),
69 };
70 }
71 }
72
73 SessionValidationResult::Valid(session.clone())
74}
75
76pub fn validate_session(
77 session: &SessionState,
78 queue: &QueueFile,
79 timeout_hours: Option<u64>,
80) -> SessionValidationResult {
81 validate_session_with_now(
82 session,
83 queue,
84 timeout_hours,
85 time::OffsetDateTime::now_utc(),
86 )
87}
88
89pub fn check_session(
90 cache_dir: &Path,
91 queue: &QueueFile,
92 timeout_hours: Option<u64>,
93) -> anyhow::Result<SessionValidationResult> {
94 let session = match load_session(cache_dir)? {
95 Some(session) => session,
96 None => return Ok(SessionValidationResult::NoSession),
97 };
98
99 Ok(validate_session(&session, queue, timeout_hours))
100}