I am trying to append callbacks to various events in a SimPy simulation, and I am finding that you can't use the yield
keyword inside a callback. Is there a way to correctly do this, or do you have to only use callbacks within callbacks?
For example, I would like the put_and_get_eggs
function to work in the following code:
import simpy
env = simpy.Environment()
foods = simpy.FilterStore(env)
foods.items = ['spam', 'eggs', 'eggs']
def test_callback(env):
print("starting")
yield foods.get(lambda x: x == "spam") & foods.get(lambda x: x == "eggs")
yield env.timeout(5)
print("items after first get using AllOf: %s" % foods.items)
t1, t2 = foods.get(lambda x: x == "spam"), foods.get(lambda x: x == "eggs")
# add callbacks to the get event. This works
t1.callbacks.append(lambda x: print(x.value + " gotten at " + str(env.now)))
t2.callbacks.append(lambda x: print(x.value + " gotten at " + str(env.now)))
yield env.timeout(1)
# Spam is put into the environment after 1 second, then immediately the callback gets called on get event
foods.put("spam")
print("spam put at %s" % env.now)
put_eggs = foods.put("eggs")
# add callbacks that include a yield, this doesn't work
def get_and_put_eggs():
print("getting eggs in callback with yield")
yield foods.get('eggs')
print("getting eggs in callback with yield")
yield env.timeout(5)
print("getting eggs in callback with yield")
yield foods.put('eggs')
print("getting eggs in callback with yield")
put_eggs.callbacks.append(get_and_put_eggs)
proc = env.process(test_callback(env))
env.run()
So far, I am able to get this to work, by defining each of the events to the right of "yield" in get_and_put_eggs
as a separate event and adding callbacks to them, but then this creates a really long and confusing callback chain. I would like to be able to do something like yield from
but I haven't been able to get this to work (such as using the line put_eggs.callbacks.append(lambda x: (yield from get_and_put_eggs))
).
Is this possible? I checked the following question, but it seems a bit different in the callback scenario, since the callback is only appended to the callback list and you can't explicitly yield from it. Python, SimPy: Using yield inside functions