Search code examples
pythonyieldsimpy

Yield hold until other line > 0


I'm using SimPy 2.3 and have a process which generates customers at an ATM at a random rate and another process which serves customers at a random rate. When the line is empty I want the ATM to wait for the next customer before doing anything else.

Here's some code

class ATM(Process):
    def Run(self):
        while 1:
            if self.atm_line.customers is 0:
                yield hold, wait for self.atm_line.customers != 0 # this is the line I'm stuck on
            yield hold, self, random.expovariate(.1)
            self.atm_line.customers -= 1

class ATM_Line(Process):
    def __init__(self):
        self.customers = 0
        Process.__init__(self)

    def Run(self):
        while 1:
            yield hold, self, random.expovariate(.1)
            self.customers += 1

initialize()
a = ATM()
a.atm_line = ATM_Line()
activate(a, a.Run())
activate(a.atm_line, a.atm_line.Run())
simulate(until=10000)

What is a good way to do this?


Solution

  • I was able to solve this problem using yield waitevent and signals. The working code is below.

    from SimPy.Simulation import *
    from random import Random, expovariate, uniform
    
    class ATM(Process):
        def Run(self):
            while 1:
                if self.atm_line.customers is 0:
                    yield waitevent, self, self.atm_line.new_customer
                yield hold, self, random.expovariate(.05)
                self.atm_line.customers -= 1
    
    class ATM_Line(Process):
        def __init__(self):
            self.customers = 0
            self.new_customer = SimEvent()
            Process.__init__(self)
    
        def Run(self):
            while 1:
                yield hold, self, random.expovariate(.07)
                self.new_customer.signal()
                self.customers += 1
    
    initialize()
    a = ATM()
    a.atm_line = ATM_Line()
    activate(a, a.Run())
    activate(a.atm_line, a.atm_line.Run())
    simulate(until=50)