Broker invokes router before requesting a resource if it handles already an...

Broker invokes router before requesting a resource if it handles already an entity. Routed updated to handle the use case
parent 78f9a9d3
...@@ -268,7 +268,7 @@ class CoreObject(Process): ...@@ -268,7 +268,7 @@ class CoreObject(Process):
self.receiver.shouldPreempt=True self.receiver.shouldPreempt=True
#======================================================= #=======================================================
# testing # testing
print now(), self.id, 'preempting receiver', self.receiver.id,'.. '*6 # print now(), self.id, 'preempting receiver', self.receiver.id,'.. '*6
#======================================================= #=======================================================
self.receiver.preempt() self.receiver.preempt()
self.receiver.timeLastEntityEnded=now() #required to count blockage correctly in the preemptied station self.receiver.timeLastEntityEnded=now() #required to count blockage correctly in the preemptied station
......
...@@ -541,7 +541,7 @@ class Machine(CoreObject): ...@@ -541,7 +541,7 @@ class Machine(CoreObject):
activeEntity=activeObjectQueue[0] activeEntity=activeObjectQueue[0]
#======================================================================= #=======================================================================
# testing # testing
print self.getActiveObjectQueue()[0].name, "Interrupted at ",self.objName, '. '*5 # print self.getActiveObjectQueue()[0].name, "Interrupted at ",self.objName, '. '*5
#======================================================================= #=======================================================================
# if the interrupt occured while processing an entity # if the interrupt occured while processing an entity
if not activeObject.waitToDispose: if not activeObject.waitToDispose:
...@@ -742,13 +742,13 @@ class Machine(CoreObject): ...@@ -742,13 +742,13 @@ class Machine(CoreObject):
if activeObject.canAccept(): if activeObject.canAccept():
# print self.id, now(), 'will try signalling a giver from removeEntity' # print self.id, now(), 'will try signalling a giver from removeEntity'
activeObject.signalGiver() activeObject.signalGiver()
# if the Machine is operated then signal Broker that the internal queue is now empty # # if the Machine is operated then signal Broker that the internal queue is now empty
if activeObject.currentOperator: # if activeObject.currentOperator:
#=================================================================== # #===================================================================
# # TESTING # # # TESTING
# print now(), self.id, 'signalling broker that removed entity' # # print now(), self.id, 'signalling broker that removed entity'
#=================================================================== # #===================================================================
activeObject.broker.victimQueueIsEmpty.signal(now()) # activeObject.broker.victimQueueIsEmpty.signal(now())
return activeEntity return activeEntity
# ======================================================================= # =======================================================================
......
...@@ -229,7 +229,7 @@ class MachineJobShop(Machine): ...@@ -229,7 +229,7 @@ class MachineJobShop(Machine):
def preempt(self): def preempt(self):
#======================================================================= #=======================================================================
# testing # testing
print now(), self.id, 'preempting', ' .'*7 # print now(), self.id, 'preempting', ' .'*7
#======================================================================= #=======================================================================
activeObject=self.getActiveObject() activeObject=self.getActiveObject()
activeEntity=self.getActiveObjectQueue()[0] #get the active Entity activeEntity=self.getActiveObjectQueue()[0] #get the active Entity
......
...@@ -91,6 +91,12 @@ class ObjectInterruption(Process): ...@@ -91,6 +91,12 @@ class ObjectInterruption(Process):
def getVictimQueue(self): def getVictimQueue(self):
return self.victim.getActiveObjectQueue() return self.victim.getActiveObjectQueue()
#===========================================================================
# check if the victim's internal queue is empty
#===========================================================================
def victimQueueIsEmpty(self):
return len(self.getVictimQueue())==0
#=========================================================================== #===========================================================================
# actions to be performed after the end of the simulation # actions to be performed after the end of the simulation
#=========================================================================== #===========================================================================
......
...@@ -49,7 +49,7 @@ class Broker(ObjectInterruption): ...@@ -49,7 +49,7 @@ class Broker(ObjectInterruption):
self.timeWaitForOperatorStarted=0 self.timeWaitForOperatorStarted=0
# Broker events # Broker events
self.isCalled=SimEvent('brokerIsCalled') self.isCalled=SimEvent('brokerIsCalled')
self.victimQueueIsEmpty=SimEvent('victimQueueIsEmpty') # self.victimQueueIsEmpty=SimEvent('victimQueueIsEmpty')
self.resourceAvailable=SimEvent('resourceAvailable') self.resourceAvailable=SimEvent('resourceAvailable')
self.waitForOperator=False self.waitForOperator=False
...@@ -78,25 +78,61 @@ class Broker(ObjectInterruption): ...@@ -78,25 +78,61 @@ class Broker(ObjectInterruption):
for type in self.victim.multOperationTypeList): for type in self.victim.multOperationTypeList):
# print now(), self.victim.id, 'broker is invoked' # print now(), self.victim.id, 'broker is invoked'
# update the time that the station is waiting for the operator # update the time that the station is waiting for the operator
self.timeWaitForOperatorStarted=now() self.timeWaitForOperatorStarted=now()
# if the resource is not available wait until a rousourceAvailable event
if not self.victim.operatorPool.checkIfResourceIsAvailable():
#===============================================================
# if the victim already holds an entity that means that the machine's operation type
# is no Load or setup, in that case the router is already invoked and the machine is already assigned an operator
from Globals import G
if not self.victimQueueIsEmpty():
# add the currentEntity to the pendingEntities
if not self.victim.currentEntity in G.pendingEntities:
G.pendingEntities.append(self.victim.currentEntity)
if not G.RoutersList[0].invoked:
#===========================================================
# testing
# print now(), self.victim.id, 'broker', ' '*50, 'signalling router'
#===========================================================
G.RoutersList[0].invoked=True
G.RoutersList[0].isCalled.signal(now())
self.waitForOperator=True self.waitForOperator=True
# print now(), self.victim.id, 'broker waits till resource is available1' # print now(), self.victim.id, 'broker waits till resource is available1'
yield waitevent, self, self.resourceAvailable yield waitevent, self, self.resourceAvailable
# remove the currentEntity from the pendingEntities
if self.victim.currentEntity in G.pendingEntities:
G.pendingEntities.remove(self.victim.currentEntity)
self.waitForOperator=False self.waitForOperator=False
# print self.victim.id, 'received resourceAvailable event' # print self.victim.id, 'received resourceAvailable event'
# if there are machines waiting for the same resources (broker.waitForOperator==True) check if they wait for longer #===============================================================
# and if yes then wait also for the same event
else:
from Globals import G
for machine in [station for station in G.MachineList if station.operatorPool is self.victim.operatorPool]:
if machine.broker.waitForOperator:
self.waitForOperator=True # # if the resource is not available wait until a rousourceAvailable event
# print now(), self.victim.id, 'broker waits till resource is available2' # if not self.victim.operatorPool.checkIfResourceIsAvailable():
yield waitevent, self, self.resourceAvailable # self.waitForOperator=True
self.waitForOperator=False # # print now(), self.victim.id, 'broker waits till resource is available1'
# print self.victim.id, 'received resourceAvailable event' # print now(), self.victim.id, 'NO OPERATOR AVAILABLE NOW, FROM BROKER',' .'*8
# yield waitevent, self, self.resourceAvailable
# self.waitForOperator=False
# # print self.victim.id, 'received resourceAvailable event'
# # if there are machines waiting for the same resources (broker.waitForOperator==True) check if they wait for longer
# # and if yes then wait also for the same event
# else:
# from Globals import G
# for machine in [station for station in G.MachineList if station.operatorPool is self.victim.operatorPool]:
# if machine.broker.waitForOperator:
# self.waitForOperator=True
# print now(), self.victim.id, 'MANY MACHINES WAITING FOR THE SAME OPERATOR, FROM BROKER',' .'*8
# # print now(), self.victim.id, 'broker waits till resource is available2'
# yield waitevent, self, self.resourceAvailable
# self.waitForOperator=False
# # print self.victim.id, 'received resourceAvailable event'
assert self.victim.operatorPool.checkIfResourceIsAvailable(), 'there is no available operator to request' assert self.victim.operatorPool.checkIfResourceIsAvailable(), 'there is no available operator to request'
# set the available resource as the currentOperator # set the available resource as the currentOperator
self.victim.currentOperator=self.victim.operatorPool.findAvailableOperator() self.victim.currentOperator=self.victim.operatorPool.findAvailableOperator()
......
...@@ -302,17 +302,22 @@ class Router(ObjectInterruption): ...@@ -302,17 +302,22 @@ class Router(ObjectInterruption):
from Globals import G from Globals import G
self.clearPending() self.clearPending()
for entity in G.pendingEntities: for entity in G.pendingEntities:
if entity.currentStation in G.MachineList:
if entity.currentStation.broker.waitForOperator:
self.pendingMachines.append(entity.currentStation)
for machine in entity.currentStation.next: for machine in entity.currentStation.next:
if any(type=='Load' for type in machine.multOperationTypeList) and not entity.currentStation in self.pendingQueues: if machine in G.MachineList:
self.pendingQueues.append(entity.currentStation) if any(type=='Load' for type in machine.multOperationTypeList) and not entity.currentStation in self.pendingQueues:
self.pendingObjects.append(entity.currentStation) self.pendingQueues.append(entity.currentStation)
break self.pendingObjects.append(entity.currentStation)
self.pendingMachines=[machine for machine in G.MachineList if machine.broker.waitForOperator] break
# self.pendingMachines=[machine for machine in G.MachineList if machine.broker.waitForOperator]
self.pendingObjects=self.pendingQueues+self.pendingMachines self.pendingObjects=self.pendingQueues+self.pendingMachines
#======================================================================= #=======================================================================
# # testing # # testing
# print 'router found pending objects' # print 'router found pending objects', [object.id for object in self.pendingObjects]
# print [object.id for object in self.pendingObjects] # print 'pendingMachines', [object.id for object in self.pendingMachines]
# print 'pendingQueues', [object.id for object in self.pendingQueues]
#======================================================================= #=======================================================================
#=========================================================================== #===========================================================================
...@@ -324,10 +329,11 @@ class Router(ObjectInterruption): ...@@ -324,10 +329,11 @@ class Router(ObjectInterruption):
for machine in self.pendingMachines: for machine in self.pendingMachines:
self.pending.append(machine.currentEntity) self.pending.append(machine.currentEntity)
for entity in G.pendingEntities: for entity in G.pendingEntities:
for machine in entity.currentStation.next: if entity.currentStation in G.QueueList or entity.currentStation in G.SourceList:
if any(type=='Load' for type in machine.multOperationTypeList): for machine in entity.currentStation.next:
self.pending.append(entity) if any(type=='Load' for type in machine.multOperationTypeList):
break self.pending.append(entity)
break
# find out which type of entities are we dealing with, managed entities or not # find out which type of entities are we dealing with, managed entities or not
if self.pending: if self.pending:
if self.pending[0].manager: if self.pending[0].manager:
...@@ -335,7 +341,8 @@ class Router(ObjectInterruption): ...@@ -335,7 +341,8 @@ class Router(ObjectInterruption):
#======================================================================= #=======================================================================
# # testing # # testing
# print 'found pending entities' # print 'found pending entities'
# print [entity.id for entity in self.pending if not entity.type=='Part'] # print 'ROUTER PENDING',[entity.id for entity in self.pending if not entity.type=='Part']
# print 'GLOBAL PENDING',[entity.id for entity in G.pendingEntities if not entity.type=='Part']
#======================================================================= #=======================================================================
#======================================================================== #========================================================================
...@@ -395,12 +402,14 @@ class Router(ObjectInterruption): ...@@ -395,12 +402,14 @@ class Router(ObjectInterruption):
if not entity.order.componentsReadyForAssembly: if not entity.order.componentsReadyForAssembly:
continue continue
# for all the possible receivers of an entity check whether they can accept and then set accordingly the canProceed flag of the entity # for all the possible receivers of an entity check whether they can accept and then set accordingly the canProceed flag of the entity
for nextObject in [object for object in entity.currentStation.next if object.canAcceptEntity(entity)]: if not entity.currentStation in self.pendingMachines:
entity.canProceed=True for nextObject in [object for object in entity.currentStation.next if object.canAcceptEntity(entity)]:
entity.candidateReceivers.append(nextObject) entity.canProceed=True
entity.candidateReceivers.append(nextObject)
# if the entity is in a machines who's broker waits for operator then # if the entity is in a machines who's broker waits for operator then
if entity.currentStation in self.pendingMachines: if entity.currentStation in self.pendingMachines:
entity.canProceed=True entity.canProceed=True
entity.candidateReceivers.append(entity.currentStation)
# if the entity can proceed, add its manager to the candidateOperators list # if the entity can proceed, add its manager to the candidateOperators list
if entity.canProceed and not entity.manager in self.candidateOperators: if entity.canProceed and not entity.manager in self.candidateOperators:
self.candidateOperators.append(entity.manager) self.candidateOperators.append(entity.manager)
...@@ -691,7 +700,6 @@ class Router(ObjectInterruption): ...@@ -691,7 +700,6 @@ class Router(ObjectInterruption):
operator.candidateEntity.candidateReceiver=operator.candidateEntity.currentStation operator.candidateEntity.candidateReceiver=operator.candidateEntity.currentStation
else: else:
operator.candidateEntity.candidateReceiver=findCandidateReceiver() operator.candidateEntity.candidateReceiver=findCandidateReceiver()
# find the resources that are 'competing' for the same station # find the resources that are 'competing' for the same station
if not self.sorting: if not self.sorting:
# if there are entities that have conflicting receivers # if there are entities that have conflicting receivers
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment