Skip to content

Resources and stores

Resources model contention for shared, finite capacity. A process yields a request and suspends until the request is granted; releasing lets the next waiter through. Every primitive here belongs to a single Sim on a single thread.

Resource

Resource is a counting semaphore: up to capacity processes hold it at once. Use request() as a context manager so the slot is always released, even on an exception or interrupt:

teller = llmsim.Resource(sim, capacity=2)

def customer(sim, teller):
    with teller.request() as slot:
        yield slot                 # granted when a slot frees
        yield sim.delay(5.0)       # hold it while served
    # slot released here

Priority and preemption

  • PriorityResource — waiters are granted in priority order (lower number = higher priority): resource.request(priority=0).
  • PreemptiveResource — a higher-priority request can evict a lower-priority holder, which sees an Interrupt at its current yield.

Container

Container models a continuous or discrete bulk quantity — fuel, cash, inventory. Processes put(amount) and get(amount); each blocks until the level allows it:

tank = llmsim.Container(sim, capacity=100.0, init=50.0)

def pump(sim, tank):
    yield tank.get(20.0)     # blocks until >= 20 available

Stores

A store holds discrete items rather than a count:

  • Store — FIFO put(item) / get().
  • PriorityStore — items come out in priority order.
  • FilterStoreget(filter=...) returns the first item matching a predicate; the natural fit for dispatch-by-attribute (e.g. an idle-vehicle pool).
idle = llmsim.FilterStore(sim)

def dispatch(sim, idle, zone):
    vehicle = yield idle.get(lambda v: v.zone == zone)   # nearest-in-zone
    # ...use vehicle, then return it...
    yield idle.put(vehicle)

All of these are re-exported at the top level (llmsim.Resource, llmsim.Container, llmsim.Store, …); see the Resources API reference for full signatures.