Machine Breakdowns: model notes
Machine with Breakdowns
Simulates a production machine subject to stochastic failures and repairs, featuring preemption of in-progress work.
Problem
A single machine processes jobs that arrive and are served according to uniform distributions. However, the machine is subject to breakdowns occurring at exponential intervals. When a breakdown occurs, it preempts whatever job is currently in service. The machine is then occupied by a repair process for a random duration. Once the repair is complete, the preempted job resumes from the exact point it was interrupted.
This model highlights the difference between "effective" utilization (time spent on actual work) and "availability" (time the machine is not broken).
This is based on Example 10 of the Schriber-GPSS/H textbook.
Model in this directory
The model uses a specialized priority system to handle disruptions:
Jobpuck (lines 42-88): Represents the work unit. It seizes the machine and advances. If it is preempted, its process is suspended by the engine.Breakdownpuck (lines 97-148): A long-lived administrative puck that cycles between waiting for a failure and performing a repair. It has a higher conceptual priority than jobs, allowing it to forcibly take the machine.sim.preemptandsim.return_preempted: These kernel primitives are used to handle the disruption.preemptkicks the current owner out and returns the remaining time on the job;return_preemptedrestores the victim and resumes their advance with that remaining time.
Why this shape
The la-preemption pattern is the core of this model. Instead of having the Job puck check for a breakdown flag, the Breakdown puck actively "steals" the resource. This is the most accurate way to model a hardware failure that happens independently of the work being performed.
To maintain accurate statistics, the model carefully manages busy_time. When a job is preempted, the unused portion of its planned advance is subtracted from the total busy time (line 121) to ensure that "busy time" only counts minutes spent actually processing a part.
Alternatives considered
- Polling for Breakdowns: A job could check a "machine_broken" flag every minute, but this would be an approximation and would not capture the exact moment of failure.
- Puck-Based Repair: One could spawn a new
Repairpuck for every failure, but using a single, cyclingBreakdownpuck is more efficient and reduces engine overhead.
What this example teaches
- Resource Preemption: Implementing "interrupt" behavior where a high-priority event displaces a lower-priority one.
- Resume-After-Interrupt: Using
sim.return_preemptedto resume a process from its exact remaining time. - Availability vs. Utilization: Distinguishing between total time a resource is occupied and time it spends on value-adding work.
Running it
odin run examples/machine_breakdowns
CLI
./machine_breakdowns [options]
Add --json to emit the uniform envelope (metadata, execution_stats,
metrics, details) instead of the default text output.
| Flag | Type | Default | Description |
|---|---|---|---|
--json |
bool | false |
Emit uniform JSON envelope instead of text. |
Example runs:
./machine_breakdowns # default text run
./machine_breakdowns --json # uniform envelope
See also
- Schriber-GPSS/H PREEMPT/RETURN chapter.
- Compare with the
widget_assemblymodel to see how breakdowns affect the bottleneck station of a production line.