def run(self): #configurar el model per consola, arxiu de text... self.configurarModel() #rellotge de simulacio a 0 self.currentTime = 0 #bucle de simulació (condició fi simulació llista buida) while self.eventList and self.currentTime <= self.maxTime: if (not self.debug): percentage = ((100 * self.simulationNum) / self.numSimulations ) + (self.currentTime / self.maxTime) * (100 / self.numSimulations) if (percentage > self.latestPercentage + self.percentageStep): self.latestPercentage = percentage print("COMPLETION: {:.2f}%".format(self.latestPercentage), end="\r") event = self.properEvent() self.eventList.remove(event) #actualitzem el rellotge de simulacio self.currentTime = event.time # deleguem l'acció a realitzar de l'esdeveniment a l'objecte que l'ha generat # també podríem delegar l'acció a un altre objecte log(self, self, "Iniciando evento " + event.type, color.HEADER) event.object.tractarEsdeveniment(event) #recollida d'estadístics self.recollirEstadistics()
def tractarEsdeveniment(self, event): log(self, self, "Procesando evento" + event.type, color.HEADER) if (event.type == "SIMULATION_START"): # comunicar a tots els objectes que cal preparar-se self.afegirEsdeveniment( Event(self.source1, 'SIMULATION_START', 0, None)) self.afegirEsdeveniment( Event(self.source2, 'SIMULATION_START', 0, None)) self.afegirEsdeveniment( Event(self.Caja1, 'SIMULATION_START', 0, None)) self.afegirEsdeveniment( Event(self.Caja2, 'SIMULATION_START', 0, None)) self.afegirEsdeveniment( Event(self.Caja3, 'SIMULATION_START', 0, None)) self.afegirEsdeveniment( Event(self.Caja4, 'SIMULATION_START', 0, None)) self.afegirEsdeveniment( Event(self.Caja5, 'SIMULATION_START', 0, None)) self.afegirEsdeveniment( Event(self.Caja6, 'SIMULATION_START', 0, None)) else: log( scheduler, self, "[WARN]: ha recibido un evento de tipo {} y no sabe cómo gestionarlo" .format(event.type), color.WARNING)
def __init__(self, scheduler, id): # inicialitzar element de simulació self.id = id self.entitatsTractades = 0 self.state = 'idle' self.scheduler = scheduler self.entitatActiva = None self.queue = None self.sink = None log(self.scheduler, self, "se ha creado", color.OKBLUE)
def afegirEsdeveniment(self, event): #inserir esdeveniment de forma ordenada if (event.time < self.currentTime): # log(self, self, "[ERROR]: Viaje en el tiempo inesperado.", color.FAIL) print( "{}[ERROR]: Viaje en el tiempo inesperado en evento {} de {}{}" .format(color.FAIL, event.type, event.object.id, color.ENDC)) event.time = self.currentTime log(self, self, "Añadiendo el evento {} en {:.2f}".format(event.type, event.time), color.OKBLUE) self.eventList.append(event) self.eventList.sort(key=self.sortEvents)
def __init__(self, scheduler, id): # inicialitzar element de simulació self.id = id self.entitatsAfegides = 0 self.state = 'idle' self.entitats = [] self.outputs = [] self.connectedQueues = [] self.scheduler = scheduler self.pesTotal = 0 self.numEntitats = 0 log(self.scheduler, self, "se ha creado", color.OKBLUE)
def tractarEsdeveniment(self, event): log(self.scheduler, self, "Procesando evento ".format(self.id) + event.type, color.HEADER) if (event.type == 'SIMULATION_START'): self.simulationStart(event) elif (event.type == 'END_SERVICE'): self.processarFiServei(event.time) else: log( self.scheduler, self, "[WARN]: ha recibido un evento de tipo {} y no sabe cómo gestionarlo" .format(event.type), color.WARNING)
def moveTo(self, container): self.container = container # Eliminar el evento de cambiar cola si se había añadido uno previamente, para que no se active depués de haber cambiado de contenedor if (self.changeQueueEvent != None): log( self.scheduler, self, "se ha movido a un nuevo contenedor, por lo que elimina su evento de cambiar de cola en {:.2f}" .format(self.changeQueueEvent.time), color.OKCYAN) self.scheduler.eliminarEsdeveniment(self.changeQueueEvent) self.changeQueueEvent = None # Si el cliente se ha movido a una cola nueva, añadir un nuevo evento de cambiar cola if (isinstance(self.container, Queue)): eventoCambiarCola = Event( self, 'CHANGE_QUEUE', self.scheduler.currentTime + Parameters.tiempoEsperaEnCola, self) self.changeQueueEvent = eventoCambiarCola log( self.scheduler, self, "se ha movido a una nueva cola, y cambiará a otra cola si no ha llegado a la caja antes de {:.2f}" .format(eventoCambiarCola.time), color.OKCYAN) self.scheduler.afegirEsdeveniment(eventoCambiarCola) elif (isinstance(self.container, Server)): log( self.scheduler, self, "ha llegado a la caja, por lo que elimina su evento de ahuecar el ala en {:.2f}" .format(self.leaveEvent.time), color.OKCYAN) self.scheduler.eliminarEsdeveniment(self.leaveEvent) self.leaveEvent = None
def __init__(self, scheduler, container, sourceId): # inicialitzar element de simulació Client.created_clients = Client.created_clients + 1 global created_clients self.id = 'Client#{}'.format(self.created_clients) self.sourceId = sourceId self.scheduler = scheduler self.pes = distribucioNormal(Parameters.tiempoEnCajaMedia, Parameters.tiempoEnCajaVarianza) self.container = container self.changeQueueEvent = None if distibucioUniforme() < Parameters.porcentajeDespistados: self.despistado = True else: self.despistado = False self.pesoEnCola = 0 self.birthTime = self.scheduler.currentTime self.leaveEvent = Event( self, 'LEAVE', self.scheduler.currentTime + Parameters.tiempoAhuecarElAla, self) log( self.scheduler, self, "se irá del supermercado si no ha llegado a la caja antes de {:.2f}" .format(self.leaveEvent.time), color.OKCYAN) self.scheduler.afegirEsdeveniment(self.leaveEvent) if (not self.sourceId in Client.total_wait_time): Client.total_wait_time[self.sourceId] = 0 if (not self.sourceId in Client.total_processed_entities): Client.total_processed_entities[self.sourceId] = 0 if (not self.sourceId in Client.total_left_clients): Client.total_left_clients[self.sourceId] = 0 if (not self.sourceId in Client.total_changed_lines): Client.total_changed_lines[self.sourceId] = 0
def recullEntitat(self, time, entitat): log(self.scheduler, self, "ha recibido una nueva entidad", color.OKCYAN) entitat.moveTo(self) self.entraEntitat(entitat) # self.numEntitats = self.numEntitats + 1 # self.pesTotal = self.pesTotal + entitat.pes idleServer = None for server in self.outputs: # print(color.OKCYAN, "[{}]: El server tiene estado".format(self.id), server.state, color.ENDC) if (server.state == 'idle'): idleServer = server if (idleServer != None): # si alguno de los outputs tiene estado "idle", enviar la entidad self.enviaProperaEntitat(time, idleServer) else: log( self.scheduler, self, "ha recibido una entidad pero ninguno de sus servers está libre", color.WARNING)
def programarFinalServei(self, time, entitat): if entitat.despistado: log( self.scheduler, self, "el cliente {} se ha dejado la cartera y se ha ido sin comprar nada" .format(entitat.id), color.OKGREEN) self.processarFiServei(time) return # que triguem a fer un servei (aleatorietat) tempsServei = entitat.pes # incrementem estadistics si s'escau self.state = 'busy' # programació final servei eventoProceso = Event(self, 'END_SERVICE', time + tempsServei, entitat) log( self.scheduler, self, "ha empezado a procesar una entidad y acabará en {:.2f}".format( eventoProceso.time), color.OKGREEN) self.scheduler.afegirEsdeveniment(eventoProceso)
def processarFiServei(self, time): log(self.scheduler, self, "ha terminado de procesar una entidad", color.OKGREEN) # Registrar estadístics self.entitatsTractades = self.entitatsTractades + 1 #sink.recullEntitat(entitat) if (self.queue.numEntitats < 1): print( "{}[ERROR]: {} decrementar el numero de clientes de {} a un valor negativo{}" .format(color.FAIL, self.id, self.queue.id, color.ENDC)) self.queue.surtEntitat(self.entitatActiva) self.entitatActiva.destroy() self.entitatActiva = None self.state = 'idle' log( self.scheduler, self, "solicita a {} que le envíe la siguiente entidad".format( self.queue.id), color.OKCYAN) self.queue.enviaProperaEntitat(time, self)
def changeToAnotherQueue(self): if (not isinstance(self.container, Queue)): print( "{}[ERROR]: {} ha intentado cambiar de cola pero estaba en {} en lugar de en una cola{}" .format(color.FAIL, self.id, self.container.id, color.ENDC)) return log(self.scheduler, self, "se ha cansado de esperar :(", color.OKCYAN) # Mirar quina cua té menys pes bestQueue = None for queue in self.container.connectedQueues: if ((bestQueue == None or queue.pesTotal < bestQueue.pesTotal) and queue.state != 'full' and queue.pesTotal <= self.pesoEnCola): bestQueue = queue # Transferir la entitat a la queue if (bestQueue): log( self.scheduler, self, "Cambia de cola de [{}] a [{}]".format(self.container.id, bestQueue.id), color.OKCYAN) Client.total_changed_lines[self.sourceId] += 1 if (self.container.numEntitats < 1): print( "{}[ERROR]: {} ha intentado decrementar el numero de clientes de {} a un valor negativo{}" .format(color.FAIL, self.id, self.container.id, color.ENDC)) # self.container.numEntitats = self.container.numEntitats - 1 # self.container.pesTotal = self.container.pesTotal - self.pes # self.container.entitats.remove(self) self.container.surtEntitat(self) bestQueue.recullEntitat(self.scheduler.currentTime, self) else: log( self.scheduler, self, "quiere cambiar de {} a otra cola, pero no hay ninguna cola a la que cambiar o todas están llenas" .format(self.container.id), color.WARNING)
def tractarEsdeveniment(self, event): log(self.scheduler, self, "Procesando evento ".format(self.id) + event.type, color.HEADER) if (event.type == 'CHANGE_QUEUE'): self.changeQueueEvent = None self.changeToAnotherQueue() elif (event.type == 'LEAVE'): if (not isinstance(self.container, Queue)): print( "{}[ERROR]: {} ha intentado ahuecar el ala pero en lugar de estar en una cola estaba en {}{}" .format(color.FAIL, self.id, self.container.id, color.ENDC)) return # self.container.numEntitats -= 1 # self.container.pesTotal -= self.pes # self.container.entitats.remove(self) self.container.surtEntitat(self) if (self.changeQueueEvent): self.scheduler.eliminarEsdeveniment(self.changeQueueEvent) self.changeQueueEvent = None log(self.scheduler, self, "se ha cansado de esperar y ha ahuecado el ala", color.FAIL) Client.total_left_clients[self.sourceId] += 1 elif (event.type == 'END_SERVICE'): self.processarFiServei(event) else: log( self.scheduler, self, "[WARN]: ha recibido un evento de tipo {} y no sabe cómo gestionarlo" .format(event.type), color.WARNING)
def enviaProperaEntitat(self, time, server): if (server.state == 'idle' and self.entitats): log(self.scheduler, self, "Envía entidad a [{}]".format(server.id), color.OKCYAN) # sacar entidad de la cola ultimaEntitat = self.entitats[0] self.entitats.remove(ultimaEntitat) # self.pesTotal = self.pesTotal - ultimaEntitat.pes (ahora hago esto en Server, para que una entidad todavía en proceso siga contando como "peso" en la cola) # enviar entidad al server server.recullEntitat(time, ultimaEntitat) elif (len(self.entitats) == 0): log( self.scheduler, self, "ha intentado enviar una entidad a {} pero ya no quedan más entidades disponibles" .format(server.id), color.WARNING) elif (server.state != 'idle'): log( self.scheduler, self, "{} se encuentra ocupada. El estado del server es = ".format( server.id), color.WARNING)
def afegirOutput(self, sink): self.sink = sink log(self.scheduler, self, "ha establecido {} como output".format(sink.id), color.OKBLUE)
def conectarAmbCua(self, queue): self.connectedQueues.append(queue) log(self.scheduler, self, "se ha conectado con la cola {}".format(queue.id), color.OKBLUE)
def afegirOutput(self, server): self.outputs.append(server) log(self.scheduler, self, "ha añadido {} como ouput".format(server.id), color.OKBLUE)
def afegirInput(self, queue): self.queue = queue log(self.scheduler, self, "ha establecido {} como input".format(queue.id), color.OKBLUE) queue.afegirOutput(self)
def recullEntitat(self, time, entitat): log(self.scheduler, self, "ha recibido una entidad", color.OKCYAN) self.entitatActiva = entitat entitat.moveTo(self) self.programarFinalServei(time, entitat)
def configurarModel(self): log(self, self, "Configurando modelo...", color.OKBLUE)