SimPy Compatibility
Every modelling feature of SimPy 4.1.2, 98 in all, with its status in YAML, the builder and the low-level API: native and checked, or not yet. A native feature is checked by conformance tests that run a plain SimPy 4.1.2 model and the same model in all three APIs, and compare event times, outcomes and balances. The page is generated from tests/conformance/register.yaml, the list the tests read, so a feature is native here only with its checks.
48 features are native and checked in all three APIs, 48 are not yet, and 2 are differences kept by design. Each feature that is not yet native becomes native in all three APIs in 0.23.0, as the Roadmap says.
The low-level API is SimPy with a few classes added, so most SimPy features work in it, those not yet checked included; SimPy and desflow explains how the two fit together. Where desflow differs from SimPy on purpose, the difference is listed under the table.
The sections are numbered by kind. C1 to C7 are SimPy's core operations, such as events, conditions, interrupts, resources and stores. S1 to S3 are support features desflow builds from those operations: breakdowns, schedules and replay. SimPy has no single call for them, so their conformance tests compare with the same behaviour written in plain SimPy.
| Section | Operations native in all three APIs |
|---|---|
| C1: Events and Processes | 9 |
| C2: Wait for One or All | 2 |
| C3: Interrupts and Preemption | 3 |
| C4: Resources | 5 |
| C5: Stores and Containers | 11 |
| C6: Run Control | 10 |
| C7: Patience | 2 |
| S1: Breakdowns | 1 |
| S2: Schedules | 1 |
| S3: Replay | 1 |
| Not Yet | none; 48 SimPy features to come |
| Differences Kept by Design | 2 differences |
Under each feature, API details opens to show its SimPy construct, its form in YAML, the builder and the low-level API, and the conformance tests that check it.
C1: Events and Processes
Waiting a fixed time, events a task can fire or fail, and processes: starting one, waiting for it, reading its return value or its failure, and inspecting an event or a process while it runs.
Timed wait: A task waits a set or sampled time, such as the time packing takes, before it goes on.
API details
- SimPy:
simpy.events.Timeout - YAML: a task with
serviceand noresource - Builder:
@app.task(service_id=...)with no resource - Low-level:
yield env.timeout(delay) - Checks:
test_c1_timed_wait - Taught on: Timed wait
Signal event success and value: One task fires a named signal with a value, and every task waiting for it wakes up and reads that value.
API details
- SimPy:
simpy.events.Event.succeed(value) - YAML:
signals: [restocked],signal: restockedon the firing task andwait: {signal: restocked} - Builder:
add_signal,@app.task(signal=...),wait={"signal": ...}, orcontext.signal(name).fire(value) - Low-level:
Signal(env, name):yield signal.wait()andsignal.fire(value) - Checks:
test_c1_signal_event_success_and_value - Taught on: Signal event success and value
Signal event failure: A signal fires as a failure, and every task waiting for it fails with the same reason.
API details
- SimPy:
simpy.events.Event.fail(exception) - YAML: a failing task with
signal; its waiters fail with its reason - Builder: the same, or
context.signal(name).fail(reason) - Low-level:
signal.fail(reason); waiters receiveSignalFailed - Checks:
test_c1_signal_event_failure - Taught on: Signal event failure
Start and wait for a process: A task starts a child flow, such as an inspection, and waits until it ends.
API details
- SimPy:
yield env.process(child()) - YAML:
wait: {task: inspect} - Builder:
wait={"task": "inspect"}, oryield context.call("inspect") - Low-level:
yield env.process(child()) - Checks:
test_c1_start_and_wait_for_a_process - Taught on: Start and wait for a process
Process return value: The task that waited for a child flow reads what the child produced.
API details
- SimPy: a process's
returnvalue - YAML:
wait.inspect.value.<field>, the last payload of the child flow - Builder: the same, or the value of
context.call(...) - Low-level:
value = yield env.process(child()) - Checks:
test_c1_process_return_value - Taught on: Process return value
Process failure: A failure inside a child flow reaches the task waiting for it, which can handle it or fail in turn.
API details
- SimPy: an exception raised in a process reaches the process that waits for it
- YAML:
fail,fail_reasonandon_failon a task; a failure noon_failhandles fails the waiting task - Builder: the same, and a function that raises fails its task
- Low-level:
try: yield env.process(child())andexcept - Checks:
test_c1_process_failure,test_c1_process_failure_handled_by_on_fail - Difference: In YAML and the builder a failure no task waits for ends the entity's flow, publishes
failedand is counted, and the run goes on; in SimPy, and in the low-level API, an exception nobody handles stops the run. - Taught on: Process failure
Event inspection: A condition reads whether a signal has fired, whether it succeeded, and its value.
API details
- SimPy:
Event.triggered,.processed,.ok,.value - YAML:
signal.<name>.count,.okand.valuein a condition - Builder:
context.signal(name).wait()and its SimPy attributes, or the signal'scount,okandvalue - Low-level: the same attributes of SimPy events and
Signal - Checks:
test_c1_event_inspection - Taught on: Event inspection
Process inspection: After a wait, a task reads whether a child flow has finished, whether it succeeded, and its value.
API details
- SimPy:
Process.is_alive,.triggered,.ok,.value - YAML:
wait.<branch>.done,.okand.valueafter the wait - Builder: the process
context.spawnandcontext.callreturn - Low-level: the process
env.processreturns - Checks:
test_c1_process_inspection - Taught on: Process inspection
Wait for a shared condition: A task waits until a condition on the model's state holds, such as stock reaching 5.
API details
- SimPy: a loop over a fresh "changed" event
- YAML:
wait: {condition: level.stock >= 5} - Builder:
wait={"condition": "level.stock >= 5"} - Low-level:
env.watch_changes(check), or a SimPy loop - Checks:
test_c1_wait_for_a_shared_condition - Taught on: Wait for a shared condition
C2: Wait for One or All
Waiting for the first of several events, or for all of them, as SimPy's AnyOf and AllOf conditions do.
Wait for one event: A task waits for whichever of several events happens first, such as a delivery or a time limit.
API details
- SimPy:
simpy.events.AnyOf,a | b - YAML:
wait: {any: {stock: {signal: restocked}, limit: {timeout: 3}}} - Builder:
wait={"any": {...}} - Low-level:
yield a | b - Checks:
test_c2_wait_for_one_event,test_c2_wait_for_one_event_two_at_one_instant - Difference: Losing signal, timeout and condition branches are dropped when the wait ends; losing child flows keep running, as SimPy leaves processes running.
- Taught on: Wait for one event
Wait for all events: A task waits until every one of several events has happened.
API details
- SimPy:
simpy.events.AllOf,a & b - YAML:
wait: {all: {...}} - Builder:
wait={"all": {...}} - Low-level:
yield a & b - Checks:
test_c2_wait_for_all_events,test_c2_wait_for_all_events_with_a_failing_branch - Taught on: Wait for all events
C3: Interrupts and Preemption
Interrupting a task while it waits or while it is in service, and a higher-priority request taking a resource unit from a lower-priority user.
Interrupt while waiting: Another task or a scenario step interrupts a task while it is still in a queue.
API details
- SimPy:
simpy.Process.interruptwhile the process waits for a request - YAML:
interrupt: {task: waiter}on a scenario step or a task;on_interrupton the task - Builder:
context.interrupt("waiter");@app.task(on_interrupt=...) - Low-level:
process.interrupt(cause), caught assimpy.Interrupt - Checks:
test_c3_interrupt_while_waiting - Taught on: Interrupt while waiting
Interrupt during service: A task is interrupted while it holds a resource, and resumes, restarts or abandons its work.
API details
- SimPy:
simpy.Process.interruptwhile the process holds a unit - YAML:
on_interrupt: resume,restartorabandon - Builder:
@app.task(on_interrupt=...) - Low-level:
except simpy.Interrupt, then request again - Checks:
test_c3_interrupt_during_service,test_c3_two_interrupts_at_one_instant - Taught on: Interrupt during service
Priority preemption: A more urgent request takes a resource unit away from a less urgent user, who is interrupted.
API details
- SimPy:
simpy.resources.resource.PreemptiveResource - YAML:
resources.<name>.preempt: truewithqueue: priority;preempt: falseon a task opts out - Builder:
add_resource(..., queue="priority", preempt=True) - Low-level:
DynamicResource(..., queue="priority", preempt=True)andrequest(priority, preempt=True) - Checks:
test_c3_priority_preemption,test_c3_priority_preemption_equal_priorities,test_c3_two_preemptions_at_one_instant,test_c3_preemption_tie_between_users,test_c3_priority_preemption_low_level - Taught on: Priority preemption
C4: Resources
Requesting and releasing resource units, in order of arrival or of priority, cancelling a request before or after its grant, and holding several resources at once.
Ordinary request and release: A task takes one unit of a resource, such as a packer, waits in line if none is free, and gives it back when done.
API details
- SimPy:
simpy.resources.resource.Resource - YAML:
resource: packerson a task - Builder:
@app.task(resource_id="packers") - Low-level:
with packers.request() as req: yield req - Checks:
test_c4_ordinary_request_and_release - Taught on: Ordinary request and release
Priority request: Waiting requests are served by priority, the lowest number first, instead of in order of arrival.
API details
- SimPy:
simpy.resources.resource.PriorityResource - YAML:
queue: priorityon the resource andpriorityon a task - Builder:
add_resource(..., queue="priority")and@app.task(priority=...) - Low-level:
DynamicResource(..., queue="priority")andrequest(priority=...) - Checks:
test_c4_priority_resource_request,test_c4_priority_request_with_mixed_preempt_flags - Difference: Equal priorities are served first in, first out, as in SimPy; desflow also offers
fifoandlifoqueues, under which a request's priority is ignored. - Taught on: Priority request
Cancel before a grant: A task leaves the queue before it is served, so it never takes a unit.
API details
- SimPy:
Request.cancel()before it is granted - YAML:
patience, or an interrupt withon_interrupt: abandon - Builder: the same
- Low-level:
request.cancel(), or leaving thewithblock - Checks:
test_c4_cancel_before_a_grant,test_c4_renege_ahead_of_a_preempting_request - Taught on: Cancel before a grant
Cancel after a grant: A task that already holds a unit stops early and gives the unit back.
API details
- SimPy:
Request.cancel()after the grant releases nothing;Resource.release(request)does - YAML: an interrupt with
on_interrupt: abandongives the unit back - Builder: the same
- Low-level:
request.cancel()releases nothing;resource.release(request) - Checks:
test_c4_cancel_after_a_grant - Taught on: Cancel after a grant
Hold several resources: A task holds more than one resource at once, taken in a fixed order, and can hand them to the next task.
API details
- SimPy: nested requests, each held while the next is awaited
- YAML:
resource: [picker, bench], acquired in that order;keephands units to the next task - Builder:
@app.task(resource_id=["picker", "bench"], keep=[...]) - Low-level: nested
withblocks - Checks:
test_c4_hold_several_resources,test_c4_keep_hands_a_unit_to_the_next_task - Difference: A model whose tasks acquire two resources in opposite orders is refused when it is built, because those tasks could each wait for ever; SimPy runs it.
- Taught on: Hold several resources
C5: Stores and Containers
Putting and getting items in a store and amounts in a container, with capacity limits, priority items, filtered gets, cancelled puts and gets, and the order of puts and gets at the same time.
Bounded store put: A task adds an item to a store, and waits when the store is full.
API details
- SimPy:
simpy.resources.store.Store.put - YAML:
put: {store: parcels}on a task - Builder:
@app.task(put={"store": "parcels"}) - Low-level:
yield parcels.put(item) - Checks:
test_c5_bounded_store_put - Taught on: Bounded store put
Bounded store get: A task takes an item from a store, and waits when the store is empty.
API details
- SimPy:
simpy.resources.store.Store.get - YAML:
get: {store: parcels}on a task - Builder:
@app.task(get={"store": "parcels"}) - Low-level:
item = yield parcels.get() - Checks:
test_c5_bounded_store_get - Taught on: Bounded store get
Equal-time puts and gets: When items are added and taken at the same moment, waiting tasks are served in the same order as in SimPy.
API details
- SimPy:
simpy.resources.store.Store, one waiting get granted per trigger - YAML:
get: {store: parcels}andput: {store: parcels}on tasks - Builder:
@app.task(get={"store": "parcels"}) - Low-level:
yield parcels.put(item),item = yield parcels.get() - Checks:
test_c5_equal_time_puts_and_gets_follow_simpy_store,test_c5_equal_time_puts_and_gets_as_tasks - Difference: While a get with a filter waits, the store grants as SimPy's
FilterStoredoes, looking at every waiting get each time. - Taught on: Equal-time puts and gets
Bounded quantity put: A task adds an amount to a container, such as boxes to stock, and waits when there is no room.
API details
- SimPy:
simpy.resources.container.Container.put - YAML:
put: {container: stock, amount: 2}on a task - Builder:
@app.task(put={"container": "stock", "amount": 2}) - Low-level:
yield stock.put(2) - Checks:
test_c5_bounded_quantity_put - Taught on: Bounded quantity put
Bounded quantity get: A task takes an amount from a container, and waits until there is enough.
API details
- SimPy:
simpy.resources.container.Container.get - YAML:
get: {container: stock, amount: 1}on a task - Builder:
@app.task(get={"container": "stock", "amount": 1}) - Low-level:
yield stock.get(1) - Checks:
test_c5_bounded_quantity_get - Taught on: Bounded quantity get
Priority item storage: Items in a store come out by priority, the lowest number first, instead of in the order they went in.
API details
- SimPy:
simpy.resources.store.PriorityStore - YAML:
stores.<name>.priority: trueand aputwithpriority - Builder:
add_store(..., priority=True)andput={"store": ..., "priority": ...} - Low-level:
DynamicStore(..., priority=True)withsimpy.PriorityItem - Checks:
test_c5_priority_item_storage - Difference: Equal priorities come out in put order in the builder and YAML, which add a rising put order to the priority; a plain SimPy
PriorityStoregives no order among equal priorities. - Taught on: Priority item storage
Filtered retrieval: A task takes only an item that matches a condition, such as a parcel for its own area.
API details
- SimPy:
simpy.resources.store.FilterStore.get(filter) - YAML:
get: {store: parcels, filter: item.area == attr.area} - Builder:
get={"store": "parcels", "filter": ...}, a condition or a function of the item - Low-level:
parcels.get(filter=lambda item: ...) - Checks:
test_c5_filtered_retrieval - Difference: A priority store takes no filter, because SimPy has no store that both ranks and filters.
- Taught on: Filtered retrieval
Cancel store get: A task stops waiting for an item, for example when its patience runs out.
API details
- SimPy:
simpy.resources.base.Get.cancel() - YAML:
patienceon a task with a storeget - Builder:
@app.task(get={"store": ...}, patience=...) - Low-level:
get.cancel() - Checks:
test_c5_cancel_store_get - Taught on: Cancel store get
Cancel quantity get: A task stops waiting for an amount from a container.
API details
- SimPy:
simpy.resources.base.Get.cancel() - YAML:
patienceon a task with a containerget - Builder:
@app.task(get={"container": ...}, patience=...) - Low-level:
get.cancel() - Checks:
test_c5_cancel_quantity_get - Taught on: Cancel quantity get
Cancel store put: A task stops waiting for room in a full store.
API details
- SimPy:
simpy.resources.base.Put.cancel() - YAML: an interrupt with
on_interrupt: abandonwhile the put waits - Builder: the same
- Low-level:
put.cancel() - Checks:
test_c5_cancel_store_put - Taught on: Cancel store put
Cancel quantity put: A task stops waiting for room in a full container.
API details
- SimPy:
simpy.resources.base.Put.cancel() - YAML: an interrupt with
on_interrupt: abandonwhile the put waits - Builder: the same
- Low-level:
put.cancel() - Checks:
test_c5_cancel_quantity_put - Taught on: Cancel quantity put
C6: Run Control
Starting a run from a given time and state, ending it at a time, at an event or on a condition, draining it, and stepping through it one event at a time.
Initial time: The simulation clock starts at a given time instead of 0.
API details
- SimPy:
simpy.core.Environment(initial_time=...) - YAML:
simulation.initial_time - Builder:
SimulationContext(..., initial_time=100) - Low-level:
DynamicRealtimeEnvironment(initial_time=100) - Checks:
test_c6_initial_time - Taught on: Initial time
Initial resources: Each resource starts with a given number of units.
API details
- SimPy:
simpy.resources.resource.Resource(capacity=...) - YAML:
resources.<name>.current_cap - Builder:
add_resource(name, current_cap=2, ...) - Low-level:
CapacityConfig(current_cap=2, ...) - Checks:
test_c6_initial_resources - Taught on: Initial resources
Initial inventory: Containers start with a given level, and stores with given items.
API details
- SimPy:
Container(init=...); items in aStore - YAML:
containers.<name>.levelandstores.<name>.items - Builder:
add_container(..., level=6)andadd_store(..., items=[...]) - Low-level:
ContainerConfig(level=6)andDynamicStore(..., items=[...]) - Checks:
test_c6_initial_inventory - Taught on: Initial inventory
Initial entity state: Each arriving entity, such as an order, starts with given attributes.
API details
- SimPy: the attributes a process starts with
- YAML:
arrivals.<name>.attributes - Builder:
add_arrival(..., attributes={...}) - Low-level: the values a process is started with
- Checks:
test_c6_initial_entity_state - Taught on: Initial entity state
Stop at a time: The run ends at a given simulation time.
API details
- SimPy:
simpy.core.Environment.run(until=...) - YAML:
run.until - Builder:
app.run(until=...) - Low-level:
env.run(until=...) - Checks:
test_c6_stop_at_a_time - Taught on: Stop at a time
Stop at an event: The run ends when a given event happens, such as a closing signal, even before its end time.
API details
- SimPy:
simpy.core.Environment.run(until=event) - YAML:
run.stop: {signal: closing}besiderun.until - Builder:
app.run(until=..., stop={"signal": "closing"}), a signal's name, or a function returning an event - Low-level:
env.run(until=event) - Checks:
test_c6_stop_at_an_event,test_c6_stop_at_an_event_at_the_same_instant_as_until - Difference: When the stop and
untilfall at the same time,untilends the run first, as SimPy's ownuntilwould. - Taught on: Stop at an event
Explicit stop condition: The run ends as soon as a condition on the model's state holds.
API details
- SimPy:
env.run(until=event)with a process that succeeds the event when the condition holds - YAML:
run.stop: {condition: level.stock >= 5} - Builder:
app.run(until=..., stop={"condition": "..."}) - Low-level:
env.watch_changes(check)andenv.run(until=event) - Checks:
test_c6_explicit_stop_condition - Taught on: Explicit stop condition
Stop arrivals and drain: New arrivals stop, and the run goes on until everything already in the model has finished.
API details
- SimPy: interrupt the source, then
env.run(until=env.all_of(entities)) - YAML:
run.drain: trueor{limit: 1 h};desflow run --drain - Builder:
app.run(until=..., drain=True), orcontext.stop_arrivals() - Low-level:
source.interrupt(), thenenv.run(until=env.all_of(processes)) - Checks:
test_c6_stop_arrivals_and_drain,test_c6_stop_arrivals_and_drain_with_a_limit - Taught on: Stop arrivals and drain
Step one event: The run advances one event at a time, so a script can watch each step.
API details
- SimPy:
simpy.core.Environment.step() - YAML:
SimulationContext.from_yaml(path).start(), then.step() - Builder:
app.start(),app.step(),app.close() - Low-level:
env.step() - Checks:
test_c6_step_one_event - Difference: A blueprint has no stepping key; its context, from
from_yaml, steps as a builder context does. - Taught on: Step one event
Inspect next event time: A script reads when the next event will happen without running it.
API details
- SimPy:
simpy.core.Environment.peek() - YAML:
SimulationContext.from_yaml(path).start(), then.peek() - Builder:
app.peek() - Low-level:
env.peek() - Checks:
test_c6_inspect_next_event_time - Taught on: Inspect next event time
C7: Patience
Customers who give up after waiting too long (reneging) and customers who do not join a queue that is too long (balking).
Reneging: A customer leaves the queue after waiting longer than their patience.
API details
- SimPy:
simpy.events.AnyOfof a request and a timeout - YAML:
patience: 3 minon a task - Builder:
@app.task(..., patience=180) - Low-level:
yield req | env.timeout(patience), thenreq.triggered - Checks:
test_c7_reneging,test_c7_reneging_tie_timeout_scheduled_after_the_grant,test_c7_reneging_tie_timeout_scheduled_before_the_grant,test_c7_reneged_request_leaves_the_queue,test_c7_patience_pauses_during_service - Taught on: Reneging
Balking: A customer does not join the queue at all when a condition holds, such as the queue being too long.
API details
- SimPy: a check before
Resource.request - YAML:
balk: <condition>on a task - Builder:
@app.task(..., balk="...") - Low-level: an
ifbefore the request - Checks:
test_c7_balking - Taught on: Balking
S1: Breakdowns
A resource that fails and is repaired, with the work it interrupts.
Breakdown and repair: A resource fails from time to time and is repaired, interrupting the work it was doing.
API details
- SimPy: a repair process holding the machine on a
PreemptiveResource - YAML:
resources.<name>.breakdown: {time_to_failure, repair, work} - Builder:
add_breakdown(resource, time_to_failure={...}, repair={...}, work=...) - Low-level:
run_breakdowns(env, resource, sampler, work=...) - Checks:
test_s1_failure_during_service,test_s1_failure_during_service_work_finishes,test_s1_planned_change_during_repair - Difference: The resource is down on a calendar clock, from the failure to the repair, even while it waits for the work in service to finish with
work: finish. - Taught on: Breakdown and repair
S2: Schedules
A schedule of times at which an arrival rate or a capacity changes during a run.
Finite schedules: Arrival rates or capacities change at set times during the run.
API details
- SimPy: a process that changes values at set times, started before the others
- YAML:
scenariosteps withat,pathandvalue - Builder:
add_scenario(steps)oradd_step(at, path=..., value=...) - Low-level:
run_scenario(env, steps, until=...) - Checks:
test_s2_step_at_an_arrival_time - Difference: A step applies before every other event at its time, so the arrival gap drawn then uses the new value.
- Taught on: Finite schedules
S3: Replay
Arrivals read from a local CSV or Parquet file instead of drawn at random.
Local replay: Arrivals come from rows in a local CSV or Parquet file instead of a random distribution.
API details
- SimPy: a loop over recorded rows, each a timeout to its time
- YAML:
arrivals.<name>.replay: {path, time, unit, fields, on_invalid} - Builder:
add_arrival_replay(name, source, ...) - Low-level:
read_trace(source, ...)and a SimPy loop over its rows - Checks:
test_s3_replay_equal_times_invalid_rows_and_the_horizon - Taught on: Local replay
Not Yet
These features are not yet native and checked in all three APIs. "Exists" marks an API that has a form, which no conformance test compares with SimPy yet, and "checked" one that a test in the Checks column compares already; the low-level API is SimPy, so many work there already.
| Feature | SimPy | YAML | Builder | Low-level | Checks | Release |
|---|---|---|---|---|---|---|
| Current time | core.Environment.now |
exists | exists | exists | none | 0.23.0 |
| Active process | core.Environment.active_process |
not yet | not yet | exists | none | 0.23.0 |
| Start a process without waiting for it | core.Environment.process |
not yet | exists | exists | none | 0.23.0 |
| Schedule an event with a priority | core.Environment.schedule |
not yet | not yet | exists | none | 0.23.0 |
| Urgent and normal event priorities | events.URGENT, events.NORMAL |
not yet | not yet | exists | none | 0.23.0 |
| A step processes only the model's events | core.Environment.step |
not yet | not yet | not yet | none | 0.23.0 |
| Value of a run stopped at an event | core.Environment.run |
not yet | not yet | exists | none | 0.23.0 |
| Run in segments | core.Environment.run, called again |
not yet | not yet | checked | test_c6_stopped_and_resumed_run |
0.23.0 |
| Subclass the environment | core.Environment |
not yet | not yet | exists | none | 0.23.0 |
| Real-time factor | rt.RealtimeEnvironment(factor) |
exists | exists | exists | none | 0.23.0 |
| Strict pacing | rt.RealtimeEnvironment.strict |
not yet | not yet | exists | none | 0.23.0 |
| Strict by default | rt.RealtimeEnvironment(strict=True) |
not yet | not yet | not yet | none | 0.23.0 |
| Sync with the wall clock | rt.RealtimeEnvironment.sync |
not yet | not yet | exists | none | 0.23.0 |
| One-shot event | events.Event |
not yet | not yet | exists | none | 0.23.0 |
| Trigger from another event | events.Event.trigger |
not yet | not yet | exists | none | 0.23.0 |
| Callbacks | events.Event.callbacks |
not yet | not yet | exists | none | 0.23.0 |
| Defused failure | events.Event.defused |
not yet | not yet | exists | none | 0.23.0 |
| Failure nobody handles | core.Environment.run |
not yet | not yet | exists | none | 0.23.0 |
| Timeout value | events.Timeout(delay, value) |
not yet | not yet | exists | none | 0.23.0 |
| Process target | events.Process.target |
not yet | not yet | exists | none | 0.23.0 |
| Process name | events.Process.name |
not yet | not yet | exists | none | 0.23.0 |
| Wait for a process already running | yield process |
not yet | exists | exists | none | 0.23.0 |
| Nested and mixed conditions | events.Condition, & and \| |
not yet | not yet | exists | none | 0.23.0 |
| A condition with a custom rule | events.Condition(env, evaluate, events) |
not yet | not yet | exists | none | 0.23.0 |
| A condition over no events | events.AnyOf(env, []) |
not yet | not yet | exists | none | 0.23.0 |
| Request, put or get as a wait branch | resources.base.Put, resources.base.Get, events.AnyOf |
not yet | not yet | exists | none | 0.23.0 |
| Put and get queues of a store or container | resources.base.BaseResource.put_queue, .get_queue |
not yet | not yet | not yet | none | 0.23.0 |
| Custom resource types | resources.base.BaseResource._do_put, ._do_get |
not yet | not yet | not yet | none | 0.23.0 |
| Custom put and get queue types | resources.base.BaseResource.PutQueue, .GetQueue |
not yet | not yet | not yet | none | 0.23.0 |
| Custom put and get event classes | resources.base.BaseResource.put, .get |
not yet | not yet | not yet | none | 0.23.0 |
| A put or get the process does not wait for | resources.base.Put without yield |
not yet | not yet | exists | none | 0.23.0 |
| Resource capacity defaults to 1 | resources.resource.Resource(capacity=1) |
not yet | not yet | not yet | none | 0.23.0 |
| Resource count | resources.resource.Resource.count |
not yet | not yet | not yet | none | 0.23.0 |
| Resource queue | resources.resource.Resource.queue |
not yet | not yet | not yet | none | 0.23.0 |
| Resource users | resources.resource.Resource.users |
not yet | exists | exists | none | 0.23.0 |
| Release event and its request | resources.resource.Release.request |
not yet | not yet | not yet | none | 0.23.0 |
| Usage since | resources.resource.Request.usage_since |
not yet | not yet | exists | none | 0.23.0 |
| Default request priority 0 | resources.resource.PriorityRequest(priority=0) |
not yet | not yet | not yet | none | 0.23.0 |
| Preemption cause | resources.resource.Preempted |
not yet | not yet | exists | none | 0.23.0 |
| A waiting line with a limit | resources.resource.SortedQueue(maxlen) |
not yet | not yet | not yet | none | 0.23.0 |
| Subclass a resource to change its rules | resources.resource.PreemptiveResource |
not yet | not yet | not yet | none | 0.23.0 |
| Container with no capacity limit | resources.container.Container(capacity=inf) |
not yet | not yet | not yet | none | 0.23.0 |
| Read a store's items | resources.store.Store.items |
not yet | exists | exists | none | 0.23.0 |
| Store with no capacity limit | resources.store.Store(capacity=inf) |
not yet | not yet | not yet | none | 0.23.0 |
| Priorities of any orderable type | resources.store.PriorityItem |
not yet | not yet | exists | none | 0.23.0 |
| Start a process after a delay | util.start_delayed |
not yet | not yet | exists | none | 0.23.0 |
| Be told when an event happens | util.subscribe_at |
not yet | not yet | exists | none | 0.23.0 |
Differences Kept by Design
- A run with no until (SimPy:
core.Environment.run()returns when no event is left): A run with a sink or an ingress connector and nountilruns for ever, because a live run has no end: the connectors keep events coming. Give it anuntil, with adrainwhen it should finish its work, or astopthat is sure to happen, or stop it with Ctrl+C. - Capacity 0 (SimPy:
resources.resource.Resource(capacity=0)raisesValueError, and so doStoreandContainer): A resource, store or container may have a capacity of 0, at the start or later, because its capacity changes during a run: a shift with no packers, a shelf that is closed. At capacity 0 a resource grants no request, and a store or container accepts no put, until the capacity rises; a get still takes what a store or container holds.