0

The code is given below. Actually, I have two nodes 0 and 1 where server capacities are 5 and 7 respectively. The servers are unavailable before 9AM (540 mins from midnight) and after 6 PM everyday. I am trying to create the unavailability using timeout but not working. I still do see items are entering nodes 0 and 1 beyond 6 PM on the second day (that is after 2520 minutes). Can't figure out the mistake. Thanks a lot!

import numpy as np
import simpy

def interarrival():
    return(np.random.exponential(20))

def servicetime():
    return(np.random.exponential(60))


def servicing(env, servers_1):
    i = 0
    while(True):
        i = i+1
        yield env.timeout(interarrival())
        print("Customer "+str(i)+ " arrived in the process at "+str(env.now))
        state = 0
        env.process(items(env, i, servers_array, state))

def items(env, customer_id, servers_array, state):
    with servers_array[state].request() as request:
        yield request
        t_arrival = env.now
        print("Customer "+str(customer_id)+ " arrived in "+str(state)+ "  at "+str(t_arrival))
        yield env.timeout(servicetime())
        t_depart = env.now
        print("Customer "+str(customer_id)+ " departed from "+str(state)+ "  at "+str(t_depart))
        if (state == 1):
            print("Customer exits")
        else:
            state = 1
            env.process(items(env, customer_id, servers_array, state))

def delay(env, servers_array):
    while(True):
        #print(servers_array[0].request())
        if (env.now%1440 >= 540 and env.now%1440 < 1080):
            yield env.timeout(1080 - env.now%1440)
        else:
            print(str(env.now), "at resources will be blocked")
            resource_unavailability_dict = dict()
            resource_unavailability_dict[0] = []
            resource_unavailability_dict[1] = []
            for nodes in resource_unavailability_dict:
                for _ in range(servers_array[nodes].capacity):
                    resource_unavailability_dict[nodes].append(servers_array[nodes].request())
            print(resource_unavailability_dict)
            for nodes in resource_unavailability_dict:
                yield env.all_of(resource_unavailability_dict[nodes])
            if (env.now < 540):
                yield env.timeout(540)
            else:
                yield env.timeout((int(env.now/1440)+1)*1440+540 - env.now)
            for nodes in resource_unavailability_dict:
                for request in resource_unavailability_dict[nodes]:
                    servers_array[nodes].release(request)
            print(str(env.now), "resources are released")
            

env = simpy.Environment()
servers_array = []
servers_array.append(simpy.Resource(env, capacity = 5))
servers_array.append(simpy.Resource(env, capacity = 7))
env.process(servicing(env, servers_array))
env.process(delay(env,servers_array))
env.run(until=2880)

1 Answers1

0

Think I found it. you are yielding to a int expressing, I think you need to wrap you int expression with a timeout event

try changing

yield(1080 - env.now%1440)

to

yield env.timeout(1080 - env.now%1440)

in def delay, I do not know what happens if your int expression passes a negative value to timeout. you may need to add a check for that

Michael
  • 1,671
  • 2
  • 4
  • 8
  • Thanks Michael, that issue is resolved. However, I am still finding issues with the making resources unavailable during a certain period. I have edited the question and given the code blob. Can you please review and tell me where am I making the mistake. Thanks a lot! – Coding Practice Nov 23 '21 at 01:15
  • do you need to use priority resources so the delay resource requests can be pushed to the front of the request queue? – Michael Nov 23 '21 at 04:06
  • Not sure. The issue that I am facing is requests are still being served by the resources after 6 PM on day 2 where there should not be any arrivals into the nodes 0 and 1 of any customers. – Coding Practice Nov 23 '21 at 04:30
  • just before adding the delay requests check the queue sizes. Check if the delay requests get granted after the existing queues gets processed. Another thing to try is just running the delay process by itself and see if it works when it starts with a empty queue. With regular resources, requests are processed fifo, so everything in the queue when the delay requests are added will be filled before the delay requests. Using priority resources you can give the delay requests a higher priority so they get bumped to the front of the line – Michael Nov 23 '21 at 05:54
  • It got resolved Michael. Thanks a lot. – Coding Practice Nov 23 '21 at 13:07