refactor coordinator to use shared lib models and client

This commit is contained in:
Timur Gordon
2025-11-13 21:56:33 +01:00
parent 4b23e5eb7f
commit 84545f0d75
16 changed files with 729 additions and 1973 deletions

View File

@@ -213,37 +213,7 @@ fn validate_flow(context_id: u32, flow: &Flow) -> Result<(), BoxError> {
Ok(())
}
fn validate_job(context_id: u32, job: &Job) -> Result<(), BoxError> {
let v = as_json(job)?;
let id = json_get_u32(&v, "id")?;
if id == 0 {
return Err(ValidationError::new("Job.id must be > 0").into());
}
let ctx = json_get_u32(&v, "context_id")?;
if ctx != context_id {
return Err(ValidationError::new(format!(
"Job.context_id ({}) does not match path context_id ({})",
ctx, context_id
))
.into());
}
let script = json_get_str(&v, "script")?;
if script.trim().is_empty() {
return Err(ValidationError::new("Job.script must not be empty").into());
}
let timeout = json_get_u32(&v, "timeout")?;
if timeout == 0 {
return Err(ValidationError::new("Job.timeout must be > 0").into());
}
let depends = json_get_array(&v, "depends")?;
if has_duplicate_u32s(&depends) {
return Err(ValidationError::new("Job.depends must not contain duplicates").into());
}
if vec_u32_contains(&depends, id) {
return Err(ValidationError::new("Job.depends must not include the job's own id").into());
}
Ok(())
}
// Validation moved to Job model - use job.validate_required_fields() and job.validate_context()
fn validate_message(context_id: u32, msg: &Message) -> Result<(), BoxError> {
let v = as_json(msg)?;
@@ -496,14 +466,14 @@ impl AppService {
if deps_ok {
// Build Message embedding this job
let ts = crate::time::current_timestamp();
let msg_id: u32 = job.id(); // deterministic message id per job for now
let msg_id: u32 = job.id.parse().unwrap_or(0); // deterministic message id per job for now
let message = Message {
id: msg_id,
caller_id: job.caller_id(),
caller_id: job.caller_id.parse().unwrap_or(0),
context_id,
message: "job.run".to_string(),
message_type: job.script_type(),
message_type: ScriptType::Python, // Default, script_type is deprecated
message_format_type: MessageFormatType::Text,
timeout: job.timeout,
timeout_ack: 10,
@@ -520,17 +490,15 @@ impl AppService {
// Persist the message and enqueue it
if redis.save_message(context_id, &message).await.is_ok() {
let _ = redis
.enqueue_msg_out(context_id, job.caller_id(), msg_id)
.await;
.enqueue_msg_out(context_id, job.caller_id, msg_id);
// Mark job as Dispatched
let _ = redis
.update_job_status(
context_id,
job.caller_id(),
job.id(),
JobStatus::Dispatched,
)
.await;
context_id,
job.caller_id,
job.id,
JobStatus::Dispatched,
);
}
}
}
@@ -579,14 +547,14 @@ impl AppService {
// Build a Message that embeds this job
let ts = crate::time::current_timestamp();
let msg_id: u32 = job.id(); // deterministic; adjust strategy later if needed
let msg_id: u32 = job.id.parse().unwrap_or(0); // deterministic; adjust strategy later if needed
let message = Message {
id: msg_id,
caller_id: job.caller_id(),
caller_id: job.caller_id.parse().unwrap_or(0),
context_id,
message: "job.run".to_string(),
message_type: job.script_type(), // uses ScriptType (matches model)
message_type: ScriptType::Python, // Default, script_type is deprecated
message_format_type: MessageFormatType::Text,
timeout: job.timeout,
timeout_ack: 10,