Example #1
0
class CheckoutLane(Component):

    base_name = 'lane'

    def __init__(self, *args, **kwargs):
        super(CheckoutLane, self).__init__(*args, **kwargs)
        self.queue = Queue(self.env)
        self.auto_probe('queue', vcd={})
        self.add_process(self.checkout)

    def __lt__(self, other):
        return self.queue.size < other.queue.size

    def enqueue(self, num_items, done_event):
        return self.queue.put((num_items, done_event))

    def checkout(self):
        scan_dist = partial(self.env.rand.expovariate,
                            1 / self.env.config['grocery.scan_time'])
        while True:
            num_items, done_event = yield self.queue.get()
            for n in range(num_items):
                yield self.env.timeout(scan_dist())
            done_event.succeed()
Example #2
0
class TankerTruck(Component):
    """Tanker trucks carry fuel to gas stations.

    Each tanker truck has a queue of gas stations it must visit. When the
    truck's tank becomes empty, it must go refill itself.

    """
    base_name = 'truck'

    def __init__(self, *args, **kwargs):
        super(TankerTruck, self).__init__(*args, **kwargs)
        self.pump_rate = self.env.config.get('tanker.pump_rate', 10)
        self.avg_travel = self.env.config.get('tanker.travel_time', 600)
        tank_capacity = self.env.config.get('tanker.capacity', 200)
        self.tank = Container(self.env, tank_capacity)

        # This auto_probe() call causes the self.tank Container to be
        # monkey-patched such that whenever it's level changes, the new level
        # is noted in the log.
        self.auto_probe('tank', log={})

        # The parent TankerCompany enqueues instructions to this queue.
        self._instructions = Queue(self.env)

        # Declare a persistant process to be started at simulation-time.
        self.add_process(self._dispatch_loop)

    def dispatch(self, gas_station, done_event):
        """Append dispatch instructions to the truck's queue."""
        return self._instructions.put((gas_station, done_event))

    def _dispatch_loop(self):
        """This is the tanker truck's main behavior. Travel, pump, refill..."""
        while True:
            if not self.tank.level:
                self.info('going for refill')

                # Desmod simulation environments come equipped with a
                # random.Random() instance seeded based on the 'sim.seed'
                # configuration key.
                travel_time = self.env.rand.expovariate(1 / self.avg_travel)
                yield self.env.timeout(travel_time)

                self.info('refilling')
                pump_time = self.tank.capacity / self.pump_rate
                yield self.env.timeout(pump_time)

                yield self.tank.put(self.tank.capacity)
                self.info('refilled {}L in {:.0f}s'.format(
                    self.tank.capacity, pump_time))

            gas_station, done_event = yield self._instructions.get()
            self.info('traveling to {}'.format(gas_station.name))
            travel_time = self.env.rand.expovariate(1 / self.avg_travel)
            yield self.env.timeout(travel_time)
            self.info('arrived at {}'.format(gas_station.name))
            while self.tank.level and (gas_station.reservoir.level <
                                       gas_station.reservoir.capacity):
                yield self.env.timeout(1 / self.pump_rate)
                yield gas_station.reservoir.put(1)
                yield self.tank.get(1)
            self.info('done pumping')
            done_event.succeed()
Example #3
0
class TankerTruck(Component):
    """Tanker trucks carry fuel to gas stations.

    Each tanker truck has a queue of gas stations it must visit. When the
    truck's tank becomes empty, it must go refill itself.

    """
    base_name = 'truck'

    def __init__(self, *args, **kwargs):
        super(TankerTruck, self).__init__(*args, **kwargs)
        self.pump_rate = self.env.config.get('tanker.pump_rate', 10)
        self.avg_travel = self.env.config.get('tanker.travel_time', 600)
        tank_capacity = self.env.config.get('tanker.capacity', 200)
        self.tank = Container(self.env, tank_capacity)

        # This auto_probe() call causes the self.tank Container to be
        # monkey-patched such that whenever it's level changes, the new level
        # is noted in the log.
        self.auto_probe('tank', log={})

        # The parent TankerCompany enqueues instructions to this queue.
        self._instructions = Queue(self.env)

        # Declare a persistant process to be started at simulation-time.
        self.add_process(self._dispatch_loop)

    def dispatch(self, gas_station, done_event):
        """Append dispatch instructions to the truck's queue."""
        return self._instructions.put((gas_station, done_event))

    def _dispatch_loop(self):
        """This is the tanker truck's main behavior. Travel, pump, refill..."""
        while True:
            if not self.tank.level:
                self.info('going for refill')

                # Desmod simulation environments come equipped with a
                # random.Random() instance seeded based on the 'sim.seed'
                # configuration key.
                travel_time = self.env.rand.expovariate(1 / self.avg_travel)
                yield self.env.timeout(travel_time)

                self.info('refilling')
                pump_time = self.tank.capacity / self.pump_rate
                yield self.env.timeout(pump_time)

                yield self.tank.put(self.tank.capacity)
                self.info('refilled {}L in {:.0f}s'.format(
                    self.tank.capacity, pump_time))

            gas_station, done_event = yield self._instructions.get()
            self.info('traveling to {}'.format(gas_station.name))
            travel_time = self.env.rand.expovariate(1 / self.avg_travel)
            yield self.env.timeout(travel_time)
            self.info('arrived at {}'.format(gas_station.name))
            while self.tank.level and (gas_station.reservoir.level <
                                       gas_station.reservoir.capacity):
                yield self.env.timeout(1 / self.pump_rate)
                yield gas_station.reservoir.put(1)
                yield self.tank.get(1)
            self.info('done pumping')
            done_event.succeed()