I'm using Simpy to simulate a queue and i need the function representing the service center to not get orders from the Store queue unless a condition is true. but when i add the if statement line all the other process in the environment stopes giving feedback as if this process it using all the computational power. i don't understand why it is acting they way it douse because it worked perfectly before i added the if statement.
here is the code for the function representing the service center:
order_queue is simpy.store(env)
format_time just formats the time into hours, minuets, and seconds
before adding the if statment:
def process_orders(env, order_queue):
while True:
order = yield order_queue.get()
print(f"{format_time(env.now)}: {order.name} in service centers")
order.exit_time = env.now
#pauses this function for the preparation time, mimicking the service center creating the order
yield env.timeout(order.prep_time)
waiting_time = order.exit_time - order.placement_time
print(f"{format_time(env.now)}: {order.name} exited at {env.now:.3f} minutes. Waiting time: {waiting_time:.3f} minutes.")
waiting_times.append(waiting_time)
after adding the if statement:
def process_orders(env, order_queue):
while True:
if (len(order_queue.items) > 0) and (round(env.now, 5) >= round(order_queue.items[-1].start_prep, 5)):
order = yield order_queue.get()
print(f"{format_time(env.now)}: {order.name} in service centers")
order.exit_time = env.now
# pauses this function for the preparation time, mimicking the service center creating the order
yield env.timeout(order.prep_time)
waiting_time = order.exit_time - order.placement_time
print(f"{format_time(env.now)}: {order.name} exited at {env.now:.3f} minutes. Waiting time: {waiting_time:.3f} minutes.")
waiting_times.append(waiting_time)
i tried to have simple if statements containing the same condition and printing when it enters them and commenting out the rest of the function. the if statements worked and i could see them printing.
another thing i tried we to debug in VScode but when i click on the next arrow it stay where it is and never gets in the if statement line.
A cursory glance of the
simpydocumentation suggests that it operates based on some form of event-based system, it needs hints to know when to wait and for how long via timeout. Generally speaking though, awhile Trueloop in Python, even for a generator, will simply have an exclusive hold the thread until ayieldis encountered. Since you have noyieldas the alternative option (i.e. in anelseblock), the thread will hold until a valid condition is matched to generate ayield.A quick fix of your issue (of no feedback) is to simply add the following:
Which will ensure that control is passed back to
simpyso that it can continue the work it was doing. A better method would be to calculate roughly the exact timeout that you need, e.g. timeout until the next order's incoming time.Moreover, this
process_ordersfunction effectively acts as a "co-routine" - this explanation largely summarizes what this means, and applying that explanation clearly shows that if the function neveryieldin a timely manner, no transfer control back to the calling function will happen (which would besimpynever be able to update/provide feedback/do anything).