Reneging and Balking
Level: Intermediate
Give a task a time limit on its wait, a condition that stops it joining at all, or both, and account for every entity afterwards. It builds on Patience, which explains both ideas, and on Resources, which explains how a request is granted.
Leave After a Wait and Refuse to Join
A task's patience is how long it may wait, for its wait, then its resource and then its get, before it leaves the queue and publishes reneged. It counts waiting time only: it pauses while the task is served, so a task that is preempted and queues again goes on with the time it has left; a get that gives up is cancelled, so it takes nothing later. Its balk is a condition checked before it joins the queue; when it holds, the task publishes balked and never asks for the resource. Here each order brings its own patience as an attribute, and no order joins after the courier's last collection at 100 seconds:
| examples/yaml/patience.yaml:pack | |
|---|---|
A low-level process writes both by hand: an if before the request, and SimPy's request | env.timeout(patience), which happens when either event does. Leaving the with block takes a waiting request out of the queue at once, so it is never granted later.
patience takes seconds, a duration such as 30 s, an expression such as attr.patience, or in the builder a function of the task id and the entity's attributes. balk takes any condition an expression can write, such as level.stock == 0.
Ties Between a Grant and a Patience
A unit can come free at the same instant a waiting order's patience runs out. Plain SimPy does not settle this with a rule: the event scheduled first is processed first. desflow grants units with the same events SimPy uses, so it gives the same answer:
- a patience timeout scheduled after the holder's service end (the order arrived at 3 with a patience of 3, the holder started at 0 with 6 seconds of service) is processed after the release, and the order is served;
- a patience timeout scheduled before it (the order arrived at 0 with a patience of 6, just after the holder) is processed first, and the order reneges.
This function runs both:
tie(3, 3) returns served and tie(0, 6) returns reneged. A model that must not depend on this order can avoid exact ties, for example by drawing patience from a distribution.
Check the Balance
Every order that arrives ends in one of four places: packed, reneged, balked, or still in the shop when the run ends, waiting (queued) or being packed (started). The last event of each entity key says which. With statistics at basic or above, the finished, reneged and balked counts must match those events:
For the example below it returns 49 packed, 7 reneged, 17 balked and 1 being packed, 74 orders in all. A mean wait counts only the orders that were served, so report the reneged and balked counts beside it.
Example
The patience example is the model above: one packer, online orders with a patience of 20 seconds and walk-in customers with 10, and no new orders from 100 seconds. It needs no Docker service and ends on its own after 120 simulation seconds.
Quick Start
desflow examples get downloads the example at the release you install, into a folder of its own. Pick uv or pip:
Quick Start
desflow examples get downloads the example at the release you install, into a folder of its own. Pick uv or pip:
Quick Start
desflow examples get downloads the example at the release you install, into a folder of its own. Pick uv or pip: