diff --git a/src/models.rs b/src/models.rs index f5f51dd..e4941cd 100644 --- a/src/models.rs +++ b/src/models.rs @@ -9,7 +9,7 @@ mod script_type; pub use actor::Actor; pub use context::Context; pub use flow::Flow; -pub use job::Job; +pub use job::{Job, JobStatus}; pub use message::{Message, MessageFormatType, MessageStatus, MessageType}; pub use runner::Runner; pub use script_type::ScriptType; diff --git a/src/storage/redis.rs b/src/storage/redis.rs index aaa07c8..7dbe60e 100644 --- a/src/storage/redis.rs +++ b/src/storage/redis.rs @@ -6,7 +6,7 @@ use serde::de::DeserializeOwned; use serde_json::{Map as JsonMap, Value}; use tokio::sync::Mutex; -use crate::models::{Actor, Context, Flow, Job, Message, Runner}; +use crate::models::{Actor, Context, Flow, Job, JobStatus, Message, Runner}; type Result = std::result::Result>; @@ -252,6 +252,35 @@ impl RedisDriver { self.hget_model(db, &key).await } + /// Atomically update a job's status and `updated_at` fields. + /// - No transition validation is performed. + /// - Writes only the two fields via HSET to avoid rewriting the whole model. + pub async fn update_job_status( + &self, + db: u32, + caller_id: u32, + id: u32, + status: JobStatus, + ) -> Result<()> { + let mut cm = self.manager_for_db(db).await?; + let key = Self::job_key(caller_id, id); + + // Serialize enum into the same plain string representation stored by create paths + let status_str = match serde_json::to_value(&status)? { + Value::String(s) => s, + v => v.to_string(), + }; + + let ts = crate::time::current_timestamp(); + + let pairs = vec![ + ("status".to_string(), status_str), + ("updated_at".to_string(), ts.to_string()), + ]; + let _: usize = cm.hset_multiple(key, &pairs).await?; + Ok(()) + } + // ----------------------------- // Message // -----------------------------