예제 #1
0
class Collector(Process):
    """Periodically collects customer happiness to a time series."""
    collect_interval = 60*10

    @Chain
    def initialize(self):
        self.stat = TSeries(storing=True, time_fnc=self.sim.clock.get, time_scale=10.0*3600)
        while True:
            self.stat.collect(100.0 * (compute_abandoned()))
            yield self.collect_interval
예제 #2
0
파일: prodcons.py 프로젝트: 2xR/legacy
class Queue(Process):
    content = None
    
    def reset(self):
        self.content = []
        self.size = Checkable(0)
        self.size_tseries = TSeries(time_fnc=self.sim.clock.get, storing=True)
        self.size_tseries.collect(0)
        self.category_ftable = FTable()
        Consumer.waiting_time.clear()
        
    def status(self):
        return self.content
        
    def put(self, obj):
        self.content.append(obj)
        self.size.set(len(self.content))
        self.size_tseries.collect(len(self.content))
        self.category_ftable.collect(obj)
        
    def get(self):
        obj = self.content.pop(0)
        self.size.set(len(self.content))
        self.size_tseries.collect(len(self.content))
        return obj
        
    def finalize(self):
        p = self.plotter = Plotter(rows=1, cols=2)
        Consumer.waiting_time.histogram(axes=p, title="Consumer waiting time")
        self.category_ftable.pie_chart(axes=p, title="Production distribution")
        self.size_tseries.run_chart(axes=p, title="Queue size time series",
                                    label="Queue size", color="green", legend=True)
예제 #3
0
파일: sfs3.py 프로젝트: 2xR/legacy
class Worker(Process):
    IDLE = "idle"
    BUSY = "busy"
    
    def constructor(self):
        self.state = TSeries()
        self.current = None
        self.tasks = Deque()
        self.operation = None
        
    def status(self):
        return "(%s, %d tasks remaining) current=%s" % (self.state.last_value, 
                                                        len(self.tasks), self.current)
        
    def reset(self):
        self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
        self.current = None
        self.tasks.clear()
        
    @Chain
    def initialize(self):
        self.state.collect(Worker.IDLE)
        while True:
            self.current = (yield self.operation.tasks.get()).result
            self.state.collect(Worker.BUSY)
            yield self.current # block until task is completed
            while len(self.tasks) > 0:
                self.current = self.tasks.popleft()
                yield self.current
            self.state.collect(Worker.IDLE)
            self.current = None
            
    def finalize(self):
        # repeat the last collected state to "close" the interval when ending a simulation
        self.state.repeat()
예제 #4
0
파일: disk.py 프로젝트: 2xR/legacy
 def reset(self):
     self.queue = []
     self.size = Checkable(0)
     self.pending = TSeries(storing=True, time_fnc=self.sim.clock.get)
     self.qtime = Tally() # queueing time
     self.stime = Tally() # service time
     self.rtime = Tally() # response time
예제 #5
0
파일: prodcons.py 프로젝트: 2xR/legacy
 def reset(self):
     self.content = []
     self.size = Checkable(0)
     self.size_tseries = TSeries(time_fnc=self.sim.clock.get, storing=True)
     self.size_tseries.collect(0)
     self.category_ftable = FTable()
     Consumer.waiting_time.clear()
예제 #6
0
파일: virus.py 프로젝트: 2xR/legacy
 def reset(self):
     self.clock.precision = 0.5
     self.members.clear()
     Virus.autoname_reset()
     for _ in xrange(Virus.initial_population):
         self.members.add(Virus())
     self.count = TSeries(storing=True, time_fnc=self.clock.get)
     self.count.collect(len(self.members))
예제 #7
0
파일: disk.py 프로젝트: 2xR/legacy
class RequestQueue(Process):
    def reset(self):
        self.queue = []
        self.size = Checkable(0)
        self.pending = TSeries(storing=True, time_fnc=self.sim.clock.get)
        self.qtime = Tally() # queueing time
        self.stime = Tally() # service time
        self.rtime = Tally() # response time
        
    def put(self, io_request):
        self.queue.append(io_request)
        self.size.set(len(self.queue))
        self.pending.collect(len(self.queue))
        
    def get(self):
        io_request = self.queue.pop(0)
        self.size.set(len(self.queue))
        self.pending.collect(len(self.queue))
        return io_request
        
    def collect(self, io_request):
        # Collect indicators about a departing request.
        self.qtime.collect(io_request.queueing_time())
        self.stime.collect(io_request.service_time())
        self.rtime.collect(io_request.response_time())
        
    def finalize(self):
        print "Mean queue size (weighted):", self.pending.wmean()
        print "Mean queueing time:", self.qtime.mean()
        print "Mean service time:", self.stime.mean()
        print "Mean responese time:", self.rtime.mean()
        self.plotter = Plotter()
        self.pending.run_chart(axes=self.plotter, label="Pending requests", legend=True)
예제 #8
0
파일: sfs1.py 프로젝트: 2xR/legacy
class Machine(Process):
    IDLE = "idle"
    BUSY = "busy"
    
    current = None
    state = TSeries()
    
    def status(self):
        return "(%s) %s" % (self.state.last_value, self.current)
        
    def reset(self):
        self.state = TSeries(numeric=False, storing=True, time_fnc=self.sim.clock.get)
        self.current = None
        
    @Chain
    def initialize(self):
        while True:
            self.state.collect(Machine.IDLE)
            self.current = None
            self.current = (yield self.parent.queue.get()).result
            #yield self.prepare()
            yield self.process()
            self.current.action.succeed()
            
    @Chain
    def process(self):
        with self.current.history.add("process", machine=self.path):
            self.state.collect(Machine.BUSY)
            yield self.current.quantity * self.current.product.complexity[self.parent.name]
            
    def finalize(self):
        self.state.repeat()
        print self.path, self.state.report()
예제 #9
0
파일: components.py 프로젝트: 2xR/legacy
 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
예제 #10
0
파일: bank.py 프로젝트: 2xR/legacy
class Server(Process):
    speed = 1.0
    customer = None
    def status(self):
        return self.customer
        
    def reset(self):
        self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
        self.customer = None
        self.pending = []
        
    #@Chain
    def initialize(self):
        while True:
            self.customer = None
            self.state.collect("idle")
            self.customer, service_time = (yield self.sim.queue.idle(self)).result
            self.state.collect("busy")
            
    def finalize(self):
        self.state.collect(self.state.last_value)
        
    def serve(self, customer, service_time):
        inactive = bool(len(self.pending) == 0) 
        service = self._serve(customer, service_time)
        self.pending.append(service)
        if inactive:
            self.action.succeed()
        return service.observe()
        
    #@Chain
    def _serve(self, customer, service_time):
        self.customer = customer
        yield service_time / self.speed
        self.customer = None
예제 #11
0
파일: bank.py 프로젝트: 2xR/legacy
class Queue(Process):
    customers = []
    def status(self):
        return "\n".join(customer.name for customer in self.customers)
        
    def reset(self):
        self.customer_requests = Deque()
        self.idle_servers = Deque()
        self.size = TSeries(time_fnc=self.sim.clock.get)
        
    def wait_for_server(self):
        """Called by a customer to enter the queue for a server."""
        return CustomerRequest(self)
        
    def _add_request(self, request):
        if len(self.idle_servers) > 0:
            request.succeed(self.idle_servers.popleft())
        else:
            self.customer_requests.append(request)
            self.size.collect(len(self.customer_requests))
            
    def _drop_request(self, request):
        self.customer_requests.remove(request)
        self.size.collect(len(self.customer_requests))
        
    def idle(self, server):
        """Called by a server after being released by a customer."""
        if len(self.customer_requests) > 0:
            self.customer_requests[0].succeed(server)
        else:
            self.idle_servers.append(server)
            
    def finalize(self):
        self.size.collect(self.size.last_value)
예제 #12
0
파일: resources.py 프로젝트: 2xR/legacy
class PhysicalCPU(Process):
    clients = []
    speed = 1.0
    
    def status(self):
        if len(self.clients) == 0:
            return "idle"
        client_speed = 100.0 / len(self.clients) * self.speed
        lines = ["%d clients (%.02f%% to each)" % (len(self.clients), client_speed)]
        lines.extend(client.path for client in self.clients)
        return "\n".join(lines)
        
    def reset(self):
        self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
        self.state.collect("Idle")
        self.clients = set()
        
    def finalize(self):
        self.state.collect("Idle" if len(self.clients) == 0 else "Busy")
        
    @Chain
    def acquire(self, client):
        yield Chain.result(self)
        if len(self.clients) == 0:
            self.state.collect("Busy")
        self.clients.add(client)
        self.update()
        
    def release(self, client):
        self.clients.remove(client)
        if len(self.clients) == 0:
            self.state.collect("Idle")
        else:
            self.update()
            
    def update(self):
        if len(self.clients) > 0:
            client_speed = self.speed / len(self.clients) 
            for client in self.clients:
                client.set_speed(client_speed)
                
    def utilization(self):
        return self.state.wrel_frequency("Busy") * 100.0
예제 #13
0
파일: resources.py 프로젝트: 2xR/legacy
class DiskFIFO(Process):
    """A first-in-first-out disk."""
    current = None
    
    def status(self):
        if self.current is None:
            return "idle"
        lines = ["%s (%d queued)" % (self.current, len(self.queue))]
        lines.extend(client.path for client in self.queue)
        return "\n".join(lines)
        
    def reset(self):
        self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
        self.state.collect("Idle")
        self.current = None
        self.queue = Deque()
        
    def finalize(self):
        self.state.collect("Idle" if self.current is None else "Busy")
        
    @Chain
    def acquire(self, client):
        yield Chain.result(self)
        if self.current is None:
            self.current = client
            self.state.collect("Busy")
            raise Chain.success()
        self.queue.append(client)
        yield Action() # suspend until activated by release()
        
    def release(self, client):
        assert client is self.current
        if len(self.queue) > 0:
            self.current = self.queue.popleft()
            self.current.action.succeed() # activate next in line
        else:
            self.current = None
            self.state.collect("Idle")
            
    def utilization(self):
        return self.state.wrel_frequency("Busy") * 100.0
예제 #14
0
파일: virus.py 프로젝트: 2xR/legacy
class VirusSim(Simulator):
    def reset(self):
        self.clock.precision = 0.5
        self.members.clear()
        Virus.autoname_reset()
        for _ in xrange(Virus.initial_population):
            self.members.add(Virus())
        self.count = TSeries(storing=True, time_fnc=self.clock.get)
        self.count.collect(len(self.members))
        
    @Chain
    def initialize(self):
        # Print time if trace is disabled.
        if not self.stack.trace:
            while True:
                print "%10.6f: %d viruses" % (self.time, len(self.members)) 
                yield 10
                
    def finalize(self):
        axes = self.count.run_chart(label="Registered growth", 
                                    title="Virus population", 
                                    legend=True)
        self.plotter = axes.figure.plotter
        print "\n" + self.count.report()
예제 #15
0
파일: callcenter2.py 프로젝트: 2xR/legacy
class Agent(Process):
    """Necessary configuration parameters:
        skills :: [skill]
        service_time :: {need: float}
    """
    client = None
    
    def status(self):
        if self.client is None:
            return "idle"
        return "%s (%s)" % (self.client.name, self.client.need)
        
    def reset(self):
        self.client = None
        self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
        
    @Chain
    def initialize(self):
        sim = self.sim
        queue = sim.members["queue"]
        self.state.collect("idle")
        while True:
            self.state.collect("idle")
            self.client = (yield queue.content.get(filter=self.can_answer)).result
            yield 0.0
            self.client.action.fail() # cause the timeout to fail
            self.state.collect("busy")
            yield self.service_time[self.client.need]
            self.client = None
            
    def finalize(self):
        results = self.sim.simulation.results
        if "utilization" not in results:
            results.utilization = Namespace()
        self.state.collect("idle" if self.client is None else "busy")
        results.utilization[self.path] = self.state.wrel_frequency("busy")
        
    def can_answer(self, client):
        # filter function for Store.content.get()
        return client.need in self.skills
예제 #16
0
파일: sfs3.py 프로젝트: 2xR/legacy
class Machine(Process):
    IDLE = "idle"
    BUSY = "busy"
    
    def constructor(self):
        self.state = TSeries()
        self.current = None
        self.operation = None
        self.channel = None
        
    def status(self):
        return "(%s) %s" % (self.state.last_value, self.current)
        
    def reset(self):
        self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
        self.current = None
        self.channel = Channel()
        
    @Chain
    def initialize(self):
        self.state.collect(Machine.IDLE)
        while True:
            lot = (yield self.operation.queue.get()).result # block until a lot is available
            load = LoadTask(lot, self)
            self.operation.tasks.append(load)
            yield load.observe() # block until operator finishes loading
            yield self.process()
            unload = UnloadTask(self)
            self.operation.tasks.append(unload)
            yield unload.observe() # block until operator finishes loading
            
    @Chain
    def process(self):
        yield self.channel.emit("Process started")
        self.state.collect(Machine.BUSY)
        duration = self.current.quantity * self.current.product.complexity[self.operation.path]
        self.process_delay = Delay(duration)
        yield self.process_delay
        self.state.collect(Machine.IDLE)
        yield self.channel.emit("Process finished")
        
    def finalize(self):
        # repeat the last collected state to "close" the interval when ending a simulation
        self.state.repeat()
예제 #17
0
파일: resources.py 프로젝트: 2xR/legacy
class VirtualCPU(PhysicalCPU):
    pCPU         = None # target for acquire() requests (may be a group of cpus)
    current_pCPU = None # pCPU where the vCPU is currently running
    
    def status(self):
        if len(self.clients) == 0:
            return "idle"
        client_speed = 100.0 / len(self.clients) * self.speed
        lines = ["%d clients (%.02f%% to each, total %.02f%% from %s)" % 
                 (len(self.clients), client_speed, self.speed * 100.0, self.current_pCPU)]
        lines.extend(client.path for client in self.clients)
        return "\n".join(lines)
        
    def reset(self):
        PhysicalCPU.reset(self)
        self.pCPU_utz = TSeries(time_fnc=self.sim.clock.get)
        self.pCPU_utz.collect(0.0)
        
    def finalize(self):
        PhysicalCPU.reset(self)
        self.pCPU_utz.collect(0.0)
        
    @Chain
    def acquire(self, client):
        yield Chain.result(self)
        if len(self.clients) == 0:
            self.current_pCPU = (yield self.pCPU.acquire(self)).result
        yield PhysicalCPU.acquire(self, client)
        
    def release(self, client):
        PhysicalCPU.release(self, client)
        if len(self.clients) == 0:
            self.current_pCPU.release(self)
            self.current_pCPU = None
            self.pCPU_utz.collect(0.0)
            
    def set_speed(self, speed):
        self.pCPU_utz.collect(speed)
        self.speed = speed
        self.update()
예제 #18
0
파일: disk.py 프로젝트: 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")
예제 #19
0
파일: sfs3.py 프로젝트: 2xR/legacy
 def reset(self):
     self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
     self.current = None
     self.tasks.clear()
예제 #20
0
파일: sfs3.py 프로젝트: 2xR/legacy
 def constructor(self):
     self.state = TSeries()
     self.current = None
     self.tasks = Deque()
     self.operation = None
예제 #21
0
파일: sfs1.py 프로젝트: 2xR/legacy
 def reset(self):
     self.state = TSeries(numeric=False, storing=True, time_fnc=self.sim.clock.get)
     self.current = None
예제 #22
0
파일: bank.py 프로젝트: 2xR/legacy
 def reset(self):
     self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
     self.customer = None
     self.pending = []
예제 #23
0
파일: bank.py 프로젝트: 2xR/legacy
 def reset(self):
     self.customer_requests = Deque()
     self.idle_servers = Deque()
     self.size = TSeries(time_fnc=self.sim.clock.get)
예제 #24
0
파일: components.py 프로젝트: 2xR/legacy
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)
예제 #25
0
파일: psqueue.py 프로젝트: 2xR/legacy
class PSQueue(Process):
    """Single-server processor sharing queue. This is used to represent how processes or threads 
    run in time-sharing mode in modern operating systems."""
    remaining = {}  # {request: remaining_servtime}
    
    def status(self):
        lines = ["%d requests" % (len(self.remaining),)]
        for request, remaining in self.remaining.iteritems():
            lines.append("%s (remaining=%f)" % (request.owner.name, remaining))
        return "\n".join(lines)
        
    def reset(self):
        self.remaining = {}
        self.ongoing = Checkable(0)
        self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
        self.finishing = False
        self.start_time = None
        
    @Chain
    def initialize(self):
        while True:
            if len(self.remaining) == 0:
                self.state.collect("Idle")
                yield Poll.greater_than(0, self.ongoing)
                self.state.collect("Busy")
            self.start_time = self.sim.time
            nprocs = len(self.remaining)
            delay = Delay(min(self.remaining.itervalues()) * nprocs)
            yield delay
            self.update()
            if delay.failed():
                # Interrupted by put_request(), wait until it exits
                yield Action()
                
    def finalize(self):
        self.state.collect("Idle" if len(self.remaining) == 0 else "Busy")
        
    def put_request(self, process, servtime):
        request = Request(servtime)
        request.bind(process)
        interrupted = False
        if len(self.remaining) > 0 and not self.finishing:
            self.action.fail()
            interrupted = True
        self.remaining[request] = servtime
        self.ongoing.set(len(self.remaining))
        if interrupted:
            self.action.succeed()
        return request
        
    def update(self):
        # Update remaining service times and check for finished requests.
        nprocs = len(self.remaining)
        elapsed = (self.sim.time - self.start_time) / nprocs
        finished = []
        for request, remaining in self.remaining.iteritems():
            # This is required because of damn floating point arithmetic errors...
            if remaining - elapsed < 1e-6: 
                finished.append(request)
            else:
                self.remaining[request] = remaining - elapsed
        # Remove finished requests.
        if len(finished) > 0:
            self.finishing = True
            for request in finished:
                del self.remaining[request]
                request.fulfill()
            self.ongoing.set(len(self.remaining))
            self.finishing = False
            
    def utilization(self):
        return self.state.wrel_frequency("Busy") * 100.0
        
예제 #26
0
파일: psqueue.py 프로젝트: 2xR/legacy
 def reset(self):
     self.remaining = {}
     self.ongoing = Checkable(0)
     self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
     self.finishing = False
     self.start_time = None
예제 #27
0
 def initialize(self):
     self.stat = TSeries(storing=True, time_fnc=self.sim.clock.get, time_scale=10.0*3600)
     while True:
         self.stat.collect(100.0 * (compute_abandoned()))
         yield self.collect_interval
예제 #28
0
파일: sfs3.py 프로젝트: 2xR/legacy
 def constructor(self):
     self.state = TSeries()
     self.current = None
     self.operation = None
     self.channel = None
예제 #29
0
파일: sfs3.py 프로젝트: 2xR/legacy
 def reset(self):
     self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
     self.current = None
     self.channel = Channel()
예제 #30
0
파일: disk.py 프로젝트: 2xR/legacy
 def reset(self):
     self.state = TSeries(numeric=False, time_fnc=self.sim.clock.get)
     self.state.collect("Idle")