71 lines
2.0 KiB
Python
71 lines
2.0 KiB
Python
"""
|
|
A collection of utility functions:
|
|
|
|
.. autosummary::
|
|
start_delayed
|
|
|
|
"""
|
|
from typing import Generator
|
|
|
|
from simpy.core import Environment, SimTime
|
|
from simpy.events import Event, Process, ProcessGenerator
|
|
|
|
|
|
def start_delayed(
|
|
env: Environment, generator: ProcessGenerator, delay: SimTime
|
|
) -> Process:
|
|
"""Return a helper process that starts another process for *generator*
|
|
after a certain *delay*.
|
|
|
|
:meth:`~simpy.core.Environment.process()` starts a process at the current
|
|
simulation time. This helper allows you to start a process after a delay of
|
|
*delay* simulation time units::
|
|
|
|
>>> from simpy import Environment
|
|
>>> from simpy.util import start_delayed
|
|
>>> def my_process(env, x):
|
|
... print(f'{env.now}, {x}')
|
|
... yield env.timeout(1)
|
|
...
|
|
>>> env = Environment()
|
|
>>> proc = start_delayed(env, my_process(env, 3), 5)
|
|
>>> env.run()
|
|
5, 3
|
|
|
|
Raise a :exc:`ValueError` if ``delay <= 0``.
|
|
|
|
"""
|
|
if delay <= 0:
|
|
raise ValueError(f'delay(={delay}) must be > 0.')
|
|
|
|
def starter() -> Generator[Event, None, Process]:
|
|
yield env.timeout(delay)
|
|
proc = env.process(generator)
|
|
return proc
|
|
|
|
return env.process(starter())
|
|
|
|
|
|
def subscribe_at(event: Event) -> None:
|
|
"""Register at the *event* to receive an interrupt when it occurs.
|
|
|
|
The most common use case for this is to pass
|
|
a :class:`~simpy.events.Process` to get notified when it terminates.
|
|
|
|
Raise a :exc:`RuntimeError` if ``event`` has already occurred.
|
|
|
|
"""
|
|
env = event.env
|
|
assert env.active_process is not None
|
|
subscriber = env.active_process
|
|
|
|
def signaller(signaller: Event, receiver: Process) -> ProcessGenerator:
|
|
result = yield signaller
|
|
if receiver.is_alive:
|
|
receiver.interrupt((signaller, result))
|
|
|
|
if event.callbacks is not None:
|
|
env.process(signaller(event, subscriber))
|
|
else:
|
|
raise RuntimeError(f'{event} has already terminated.')
|