// scheduler/job.mbt
// Defines the Job abstraction: a unit of work with an arrival time, service
// time, deadline, and priority, together with its lifecycle status.
///|
/// Enumeration of all possible lifecycle states a Job can occupy.
pub(all) enum JobStatus {
/// Waiting in a queue for a free executor slot.
Queued
/// Currently being executed by an executor.
Running
/// Finished execution successfully before its deadline.
Completed
/// Execution was cancelled before it could finish.
Cancelled
/// The job exceeded its deadline and was forcibly evicted.
DeadlineMissed
} derive(Debug, Eq)
///|
pub impl Show for JobStatus with fn output(self, logger) {
let s = match self {
Queued => "Queued"
Running => "Running"
Completed => "Completed"
Cancelled => "Cancelled"
DeadlineMissed => "DeadlineMissed"
}
logger.write_string(s)
}
///|
/// A schedulable unit of work.
///
/// Each Job carries:
/// - `id`: globally unique integer identifier.
/// - `arrival_time`: the simulation time (seconds) when the job entered the system.
/// - `service_time`: the duration (seconds) the job requires on an executor.
/// - `deadline`: optional absolute time limit (seconds); `None` means no deadline.
/// - `priority`: scheduling priority �?lower values are processed first.
/// - `status`: mutable lifecycle state.
/// - `start_time`: set when execution begins.
/// - `finish_time`: set when execution completes or is aborted.
pub(all) struct Job {
id : Int
arrival_time : Double
service_time : Double
deadline : Double?
priority : Int
mut status : JobStatus
mut start_time : Double?
mut finish_time : Double?
}
///|
pub fn Job::new(
id : Int,
arrival_time : Double,
service_time : Double,
deadline : Double?,
priority : Int,
) -> Job {
if service_time <= 0.0 {
abort("Job service_time must be positive")
}
{
id,
arrival_time,
service_time,
deadline,
priority,
status: Queued,
start_time: None,
finish_time: None,
}
}
///|
/// Returns the wall-clock waiting time: time from arrival until the job
/// started running. Returns `None` if the job has not yet started.
pub fn Job::wait_time(self : Job) -> Double? {
match self.start_time {
None => None
Some(s) => Some(s - self.arrival_time)
}
}
///|
/// Returns the total sojourn time: time from arrival until the job finished.
/// Returns `None` if the job has not yet finished.
pub fn Job::sojourn_time(self : Job) -> Double? {
match self.finish_time {
None => None
Some(f) => Some(f - self.arrival_time)
}
}
///|
/// Returns `true` if this job has missed its deadline.
/// A job misses its deadline when its `finish_time` (or the current time,
/// if still running) exceeds `deadline`.
pub fn Job::has_missed_deadline(self : Job, now : Double) -> Bool {
match self.deadline {
None => false
Some(dl) =>
match self.finish_time {
Some(f) => f > dl
None => now > dl
}
}
}