Reputation: 73
I'm trying to simulate a queue with limited buffer where no packet is dropped but kept in waiting . Bear with me since I'm just a student with basic coding skills.
The packet arrive exponentially distributed and each hold a packet size with mean 1250 bytes. I managed to get the code working for packet arrival + processing time but i couldn't make the packet 'depart' and also simulating the queue (so far, it is with unlimited buffer) Is there anything I could do to simulate the packet departure and the queue limit?
code:
import random
import simpy
RANDOM_SEED = 42
NEW_CUSTOMERS = 100 # Total number of customers
INTERVAL_CUSTOMERS = 1 # Generate new customers roughly every x seconds
SIZE = 1250
def source(env, number, interval, port):
"""Source generates packet randomly"""
for i in range(number):
size = int(random.expovariate(0.0008))
packet = Packet(env, '%d' % i, size, port, time_in_port=1)
env.process(packet)
t = random.expovariate(1 / interval)
yield env.timeout(t)
def Packet(env, id, size, port, time_in_port):
arrive = env.now
yield Queue.buffer.put(size)
print('packet%s %s arriving at %lf' % (id, size, arrive))
with port.request() as req:
yield req
tip = random.expovariate(1/time_in_port)
yield env.timeout(tip)
amount = size
yield Queue.buffer.get(amount)
print('packet%s %s finished processing at %lf' % (id, size, env.now))
class queue: #THIS PART WON'T WORK
def __init__(self, env):
self.port = simpy.Resource(env, capacity=1)
self.buffer = simpy.Container(env, init = 0, capacity=12500)
self.mon_proc = env.process(self.monitor_tank(env))
def monitor_tank(self, env):
while True:
if self.buffer.level > 12500:
print('Full at %d' % env.now)
random.seed(RANDOM_SEED)
env = simpy.Environment()
Queue = queue(env)
port = simpy.Resource(env, capacity=1)
env.process(source(env, NEW_CUSTOMERS, INTERVAL_CUSTOMERS, port))
env.run()
The queue class didn't work (The program won't run at all). It will run if only I remove the queue class and simulate packet arrival and processing time. Would appreciate any help to make me simulate the packet departure(using a sink) and the queue limit. Thanks.
Upvotes: 1
Views: 3241
Reputation: 107
Hello I think the code will solve your problem or at least give you a direction. As in your original code all the packages have the same size, I modelled in this packages, but to change to bytes is straight forward.
I used a buffer (container) and a server (resource).
;)
import simpy
import random
def arrival(env, buffer):
#Arrival of the Package
while True:
print('Package ARRIVED at %.1f \n\t Buffer: %i'
% (env.now, buffer.level))
yield buffer.put(1) # Put the package in the buffer
yield env.timeout(random.expovariate(1.0)) # time between arrivals
env.process(processDeparture(env, buffer, server))
def processDeparture(env, buffer, server):
#Processing and Departure of the Package
while True:
# request a Server to process thge package
request = server.request()
yield request
yield buffer.get(1) # GET a package from the buffer
# Processing time of the package
processingTime = 2
print('Package begin processing at %.1f'
% (env.now))
yield env.timeout(processingTime)
print('Package end processing at %.1f'
% (env.now))
# release the server
yield server.release(request)
random.seed(150)
env = simpy.Environment()
buffer = simpy.Container(env, capacity=3, init=0) # Create the Buffer
server = simpy.Resource(env, capacity=1) # Create the servers (resources)
env.process(arrival(env, buffer))
env.run(until=30) # Execute the Model
Upvotes: 0
Reputation: 1914
I think this code from your code is a infinite loop and is blocking your code from running
def monitor_tank(self, env):
while True:
if self.buffer.level > 12500:
print('Full at %d' % env.now)
Try commenting This piece out, or adding a env.timeout so it "sleeps" for a bit on every loop pass
Upvotes: 1
Reputation: 7284
Not familiar with the details, but your call to self.monitor_tank(env)
in the queue
constructor is going to go into a tight infinite loop - it isn't a generator, just an unending loop, so python is going to get stuck at that point in the execution.
Upvotes: 2