Ejemplo n.º 1
0
Archivo: disk.py Proyecto: 2xR/legacy
class Disk(Process):
    mean_service_time = 0.02 # Mean service time for one IO request.
    
    def reset(self):
        self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
        self.state.collect("Idle")
        
    @Chain
    def initialize(self):
        sim = self.sim
        queue = sim.members["Queue"]
        while True:
            if queue.size.get() == 0:
                self.state.collect("Idle")
                yield Poll.greater_than(0, queue.size)
                self.state.collect("Busy")
            io_request = queue.get()
            io_request.service = sim.time
            yield sample.nonnegative(sim.rng.expovariate, 1.0 / Disk.mean_service_time)
            io_request.departure = self.sim.time
            queue.collect(io_request)
            
    def finalize(self):
        queue = self.sim.members["Queue"]
        if queue.running:
            queue.stop()  # Make sure to finalize the queue before the disk.
        self.state.collect(self.state.last_value())
        self.state.pareto_chart(axes=queue.plotter, title=self.name)
        print self, "utilization:", self.state.wrel_frequency("Busy")
Ejemplo n.º 2
0
class WorkStation(Process):
    """Configuration parameters:
        initial_workers :: int
        throughput_fnc :: callable(int) -> float
        changeover :: {(from, to): float}
        setup :: {product: float}
    """
    state = TSeries()
    workers = Checkable(0)
    throughput = 0.0
    current = None
    initial_workers = 0
    changeover = {}
    setup = {}
    
    def set_workers(self, workers):
        """This method is used by the line balancer to adjust the number of workers in each  
        assembly line and/or the workbenches, and update their throughput."""
        self.throughput = self.throughput_fnc(workers)
        self.workers.set(workers)
        
    def throughput_fnc(self, workers):
        raise NotImplementedError()
        
    def status(self):
        return "%d workers (throughput=%f) - %s - %s" % \
        (self.workers.get(), self.throughput, self.state.last_value(), self.current)
        
    def reset(self):
        if "queue" not in self:
            self["queue"] = Store()
        self["queue"].content.clear()
        self.state = TSeries(storing=False, numeric=False, time_fnc=self.sim.clock.get)
        self.workers = Checkable(self.initial_workers)
        self.throughput = self.throughput_fnc(self.initial_workers)
        self.current = None
        self.previous = None
        
    @Chain
    def initialize(self):
        queue = self["queue"]
        while True:
            yield self.fetch(queue)
            yield self.prepare(self.current.product)
            yield self.process(self.current)
            self.previous = self.current.product
            self.current.action.succeed()
            self.current = None
            
    @Chain
    def fetch(self, queue):
        """Get the order with minimum preparation time and maximum process time from the queue."""
        self.state.collect(IDLE)
        if len(queue.content) == 0:
            self.current = (yield queue.content.get()).result
        else:
            best_score = None
            best_order = None
            for order in queue.content:
                changeover = self.changeover.get((self.previous, order.product), 0.0)
                setup      = self.setup.get(order.product, 0.0)
                ptime      = order.quantity * order.product.complexity[self.name]
                score      = (-(changeover + setup), +ptime)
                if score > best_score:
                    best_score = score
                    best_order = order
            queue.content.remove(best_order)
            self.current = best_order
        self.current.location = self.name
        
    @Chain
    def prepare(self, product):
        """Prepare the workstation for processing the specified product. This may include a 
        changeover if the product is different from the one previously processed, and a setup 
        time for preparing the machinery to start working."""
        self.state.collect(CHANGEOVER)
        yield self.changeover.get((self.previous, product), 0.0)
        self.state.collect(SETUP)
        yield self.setup.get(product, 0.0)
        
    @Chain
    def process(self, order):
        """Simulate the processing of 'order' with a possibly variable number of workers."""
        self.state.collect(BUSY)
        remaining = order.quantity
        while True:
            if self.workers.get() == 0:
                self.state.collect(NO_WORKERS)
                yield Poll.greater_than(0, self.workers)
                self.state.collect(BUSY)
            rate = self.throughput / order.product.complexity[self.name]
            process = Delay(remaining / rate)
            yield Renege(process, Poll.not_equal_to(self.workers.get(), self.workers))
            remaining -= process.elapsed_time * rate
            if process.succeeded():
                raise Chain.success()
                
    def finalize(self):
        self.state.collect(self.state.last_value())
        self.state.pareto_chart(axes=self.sim.plotter, title=self.name)