3.7 KiB
3.7 KiB
Job Format
Jobs are the fundamental unit of work in Horus.
Structure
pub struct Job {
pub id: String, // Unique job identifier
pub runner_id: String, // Target runner ID
pub payload: String, // Job payload (script/command)
pub timeout: Option<u64>, // Timeout in seconds
pub env_vars: HashMap<String, String>, // Environment variables
pub signatures: Vec<Signature>, // Cryptographic signatures
pub created_at: i64, // Creation timestamp
pub status: JobStatus, // Current status
}
Job Status
pub enum JobStatus {
Pending, // Queued, not yet started
Running, // Currently executing
Completed, // Finished successfully
Failed, // Execution failed
Timeout, // Exceeded timeout
Cancelled, // Manually cancelled
}
Signature Format
pub struct Signature {
pub public_key: String, // Signer's public key
pub signature: String, // Cryptographic signature
pub algorithm: String, // Signature algorithm (e.g., "ed25519")
}
Creating a Job
Minimal Job
use hero_job::Job;
let job = Job::new(
"my-runner",
"print('Hello World')".to_string(),
);
With Timeout
let job = Job::builder()
.runner_id("my-runner")
.payload("long_running_task()")
.timeout(300) // 5 minutes
.build();
With Environment Variables
use std::collections::HashMap;
let mut env_vars = HashMap::new();
env_vars.insert("API_KEY".to_string(), "secret".to_string());
env_vars.insert("ENV".to_string(), "production".to_string());
let job = Job::builder()
.runner_id("my-runner")
.payload("deploy_app()")
.env_vars(env_vars)
.build();
With Signature
use hero_job::{Job, Signature};
let job = Job::builder()
.runner_id("my-runner")
.payload("important_task()")
.signature(Signature {
public_key: "ed25519:abc123...".to_string(),
signature: "sig:xyz789...".to_string(),
algorithm: "ed25519".to_string(),
})
.build();
Payload Format
The payload format depends on the target runner:
Hero Runner
Heroscript content:
!!git.list
print("Repositories listed")
!!docker.ps
SAL Runner
Rhai script with SAL modules:
let files = os.list_dir("/tmp");
for file in files {
print(file);
}
Osiris Runner
Rhai script with Osiris database:
let users = osiris.model("users");
let user = users.create(#{
name: "Alice",
email: "alice@example.com"
});
Job Result
pub struct JobResult {
pub job_id: String,
pub status: JobStatus,
pub output: String, // Stdout
pub error: Option<String>, // Stderr or error message
pub exit_code: Option<i32>,
pub started_at: Option<i64>,
pub completed_at: Option<i64>,
}
Best Practices
Timeouts
- Always set timeouts for jobs
- Default: 60 seconds
- Long-running jobs: Set appropriate timeout
- Infinite jobs: Use separate monitoring
Environment Variables
- Don't store secrets in env vars in production
- Use vault/secret management instead
- Keep env vars minimal
- Document required variables
Signatures
- Always sign jobs in production
- Use strong algorithms (ed25519)
- Rotate keys regularly
- Store private keys securely
Payloads
- Keep payloads concise
- Validate input data
- Handle errors gracefully
- Log important operations
Validation
Jobs are validated before execution:
- Structure: All required fields present
- Signature: Valid cryptographic signature
- Runner: Target runner exists and available
- Payload: Non-empty payload
- Timeout: Reasonable timeout value
Invalid jobs are rejected before execution.