Just like this question, I don't understand what triggered means for a SimPy event. The only answer posted does not clarify it for me.
The docs say an event:
I originally thought those corresponded to:
But then I found through experimentation that was wrong. I have not been able to create an example for which I can print p.triggered
and p.processed
for some process p
and have the first be True
and the second False
. They're always either both True
or both False
.
So my question is, can anyone give code of an example (ideally as simple as possible) for which there exists some moment of time that a process is triggered but not processed?
Ideally, it would include an explanation of "triggered" that matches the example.
This stuff is not clear, but my understanding is that when you use env.process() to convert one of your processes to a event, that event does not get triggered until you exit your process, not when it hits a yield. So if you write a process with a infinite loop, it will always be in that might happen (not triggered) state.
Events are not marked as processed until all events that can be triggered at a time x, are triggered. I think this allows for events to talk to each other and add callbacks, before callbacks get executed. I'm not sure what happens if a callback creates a new event that is immediately triggered.
here is some code to show the event flow
"""
Quick demo showing the states of events over time
Three events are created which all expire at the same time.
One event has a callback
Looks like events are not marked as triggered until they exit their process.
And callback are not processed until all triggering is done.
Programmer: Michael R. Gibbs
"""
import simpy
class EventCheck():
"""
class with a event process that checks the state
of a list of events.
"""
def __init__(self, env, name):
self.eventList = []
self.env = env
self.name = name
# create the event
self.e = self.env.process(self.e_process())
def set_event_list(self, list):
"""
The list of objects of this class type
"""
self.eventList = list
def check_events(self):
"""
print out the state of a list of events
"""
for obj in self.eventList:
print(obj.name, obj.e.triggered, obj.e.processed)
def e_process(self):
"""
The event that get turned into a evnet with env.process()
call the method that prints out the states of a list of events
"""
print(self.env.now, self.name, "created")
yield self.env.timeout(2)
print(self.env.now,self.name, "timeout finished")
self.check_events()
print(self.env.now,self.name, "finish process")
def pre_check(env, list):
"""
Prints out the states of a event before its trigger time
"""
yield env.timeout(1)
print(env.now, "pre trigger")
list[0].check_events()
def watcher(env, e):
"""
Shows how a process sees a event
"""
print(env.now, "watching")
print(e.triggered, e.processed)
yield e
print(env.now, "done watching")
print(e.triggered, e.processed)
def my_callback(e):
"""
Shows how a callback sees a event calling it
"""
print("callback")
print(e.triggered, e.processed)
env = simpy.Environment()
# create three events checkers, each has its own event
e_list = [
EventCheck(env, "e1"),
EventCheck(env, 'e2'),
EventCheck(env, 'e3'),
]
# give one event a callback
e_list[0].e.callbacks.append(my_callback)
# assing each checker the same list of events
for e in e_list:
e.set_event_list(e_list)
# start the other process that show a events state
env.process(pre_check(env, e_list))
env.process(watcher(env, e_list[0].e))
env.run(10)
# show a events state after its trigger time
print(env.now, "post trigger")
e_list[0].check_events()
and here is the output I got
0 e1 created
0 e2 created
0 e3 created
0 watching
False False
1 pre trigger
e1 False False
e2 False False
e3 False False
2 e1 timeout finished
e1 False False
e2 False False
e3 False False
2 e1 finish process
2 e2 timeout finished
e1 True False
e2 False False
e3 False False
2 e2 finish process
2 e3 timeout finished
e1 True False
e2 True False
e3 False False
2 e3 finish process
callback
True True
2 done watching
True True
10 post trigger
e1 True True
e2 True True
e3 True True