Machine, if no router is initiated then the pendingEntities list is not...

Machine, if no router is initiated then the pendingEntities list is not populated by endProcessingActions(). getActiveObject() used less to speed up
parent 78398fa9
...@@ -228,12 +228,12 @@ class Machine(CoreObject): ...@@ -228,12 +228,12 @@ class Machine(CoreObject):
while 1: while 1:
# waitEvent isRequested /interruptionEnd/loadOperatorAvailable # waitEvent isRequested /interruptionEnd/loadOperatorAvailable
while 1: while 1:
self.printTrace(self.id, waitEvent='') # self.printTrace(self.id, waitEvent='')
yield waitevent, self, [self.isRequested, self.interruptionEnd, self.loadOperatorAvailable] yield waitevent, self, [self.isRequested, self.interruptionEnd, self.loadOperatorAvailable]
self.printTrace(self.id, received='') # self.printTrace(self.id, received='')
# if the machine can accept an entity and one predecessor requests it continue with receiving the entity # if the machine can accept an entity and one predecessor requests it continue with receiving the entity
if self.isRequested.signalparam: if self.isRequested.signalparam:
self.printTrace(self.id, isRequested=self.isRequested.signalparam.id) # self.printTrace(self.id, isRequested=self.isRequested.signalparam.id)
assert self.isRequested.signalparam==self.giver, 'the giver is not the requestingObject' assert self.isRequested.signalparam==self.giver, 'the giver is not the requestingObject'
assert self.giver.receiver==self, 'the receiver of the signalling object in not the station' assert self.giver.receiver==self, 'the receiver of the signalling object in not the station'
# reset the signalparam of the isRequested event # reset the signalparam of the isRequested event
...@@ -242,10 +242,10 @@ class Machine(CoreObject): ...@@ -242,10 +242,10 @@ class Machine(CoreObject):
# if an interruption caused the control to be taken by the machine or # if an interruption caused the control to be taken by the machine or
# if an operator was rendered available while it was needed by the machine to proceed with getEntity # if an operator was rendered available while it was needed by the machine to proceed with getEntity
if self.interruptionEnd.signalparam==now() or self.loadOperatorAvailable.signalparam==now(): if self.interruptionEnd.signalparam==now() or self.loadOperatorAvailable.signalparam==now():
if self.interruptionEnd.signalparam==now(): # if self.interruptionEnd.signalparam==now():
self.printTrace(self.id, interruptionEnd=str(self.interruptionEnd.signalparam)) # self.printTrace(self.id, interruptionEnd=str(self.interruptionEnd.signalparam))
elif self.loadOperatorAvailable.signalparam==now(): # elif self.loadOperatorAvailable.signalparam==now():
self.printTrace(self.id,loadOperatorAvailable=str(self.loadOperatorAvailable.signalparam)) # self.printTrace(self.id,loadOperatorAvailable=str(self.loadOperatorAvailable.signalparam))
# try to signal the Giver, otherwise wait until it is requested # try to signal the Giver, otherwise wait until it is requested
if self.signalGiver(): if self.signalGiver():
break break
...@@ -467,16 +467,15 @@ class Machine(CoreObject): ...@@ -467,16 +467,15 @@ class Machine(CoreObject):
# actions to be carried out when the processing of an Entity ends # actions to be carried out when the processing of an Entity ends
# ======================================================================= # =======================================================================
def endProcessingActions(self): def endProcessingActions(self):
activeObject=self.getActiveObject() activeObjectQueue=self.Res.activeQ
activeObjectQueue=activeObject.getActiveObjectQueue()
activeEntity=activeObjectQueue[0] activeEntity=activeObjectQueue[0]
self.printTrace(activeObject.getActiveObjectQueue()[0].name, processEnd=activeObject.objName) # self.printTrace(activeObject.getActiveObjectQueue()[0].name, processEnd=activeObject.objName)
# reset the variables used to handle the interruptions timing # reset the variables used to handle the interruptions timing
self.timeRestartingProcessing=0 self.timeRestartingProcessing=0
self.breakTime=0 self.breakTime=0
# output to trace that the processing in the Machine self.objName ended # output to trace that the processing in the Machine self.objName ended
try: try:
activeObject.outputTrace(activeObject.getActiveObjectQueue()[0].name,"ended processing in "+activeObject.objName) self.outputTrace(activeObjectQueue[0].name,"ended processing in "+self.objName)
except IndexError: except IndexError:
pass pass
# TODO: Not only Machines require time to process entities # TODO: Not only Machines require time to process entities
...@@ -484,32 +483,33 @@ class Machine(CoreObject): ...@@ -484,32 +483,33 @@ class Machine(CoreObject):
if activeEntity.family=='Entity': if activeEntity.family=='Entity':
successorsAreMachines=True successorsAreMachines=True
from Globals import G from Globals import G
for object in activeObject.next: for object in self.next:
if not object in G.MachineList: if not object in G.MachineList:
successorsAreMachines=False successorsAreMachines=False
break break
if not successorsAreMachines: if not successorsAreMachines:
activeObjectQueue[0].hot = False activeObjectQueue[0].hot = False
from Globals import G from Globals import G
# the just processed entity is added to the list of entities if G.Router:
# pending for the next processing # the just processed entity is added to the list of entities
G.pendingEntities.append(activeObjectQueue[0]) # pending for the next processing
G.pendingEntities.append(activeObjectQueue[0])
# set the variable that flags an Entity is ready to be disposed # set the variable that flags an Entity is ready to be disposed
activeObject.waitToDispose=True self.waitToDispose=True
#do this so that if it is overtime working it is not counted as off-shift time #do this so that if it is overtime working it is not counted as off-shift time
if not activeObject.onShift: if not self.onShift:
activeObject.timeLastShiftEnded=now() self.timeLastShiftEnded=now()
# update the total working time # update the total working time
# the total processing time for this entity is what the distribution initially gave # the total processing time for this entity is what the distribution initially gave
if not self.shouldPreempt: if not self.shouldPreempt:
activeObject.totalWorkingTime+=activeObject.totalProcessingTimeInCurrentEntity self.totalWorkingTime+=self.totalProcessingTimeInCurrentEntity
# if the station was preemptied for a critical order then calculate the total working time accorindingly # if the station was preemptied for a critical order then calculate the total working time accorindingly
else: else:
activeObject.totalWorkingTime+=now()-(self.timeLastEntityEntered) self.totalWorkingTime+=now()-(self.timeLastEntityEntered)
# update the variables keeping track of Entity related attributes of the machine # update the variables keeping track of Entity related attributes of the machine
activeObject.timeLastEntityEnded=now() # this holds the time that the last entity ended processing in Machine self.timeLastEntityEnded=now() # this holds the time that the last entity ended processing in Machine
activeObject.nameLastEntityEnded=activeObject.currentEntity.name # this holds the name of the last entity that ended processing in Machine self.nameLastEntityEnded=self.currentEntity.name # this holds the name of the last entity that ended processing in Machine
activeObject.completedJobs+=1 # Machine completed one more Job self.completedJobs+=1 # Machine completed one more Job
# reseting the shouldPreempt flag # reseting the shouldPreempt flag
self.shouldPreempt=False self.shouldPreempt=False
...@@ -517,15 +517,14 @@ class Machine(CoreObject): ...@@ -517,15 +517,14 @@ class Machine(CoreObject):
# actions to be carried out when the processing of an Entity ends # actions to be carried out when the processing of an Entity ends
# ======================================================================= # =======================================================================
def interruptionActions(self): def interruptionActions(self):
activeObject=self.getActiveObject() activeObjectQueue=self.Res.activeQ
activeObjectQueue=activeObject.getActiveObjectQueue()
activeEntity=activeObjectQueue[0] activeEntity=activeObjectQueue[0]
self.printTrace(self.getActiveObjectQueue()[0].name, interrupted=self.objName) # self.printTrace(activeEntity.name, interrupted=self.objName)
# if the interrupt occured while processing an entity # if the interrupt occured while processing an entity
if not activeObject.waitToDispose: if not self.waitToDispose:
# output to trace that the Machine (self.objName) got interrupted # output to trace that the Machine (self.objName) got interrupted
try: try:
self.outputTrace(self.getActiveObjectQueue()[0].name, "Interrupted at "+self.objName) self.outputTrace(activeObjectQueue[0].name, "Interrupted at "+self.objName)
except IndexError: except IndexError:
pass pass
# recalculate the processing time left tinM # recalculate the processing time left tinM
...@@ -542,18 +541,17 @@ class Machine(CoreObject): ...@@ -542,18 +541,17 @@ class Machine(CoreObject):
# actions to be carried out when the processing of an Entity ends # actions to be carried out when the processing of an Entity ends
# ======================================================================= # =======================================================================
def postInterruptionActions(self): def postInterruptionActions(self):
activeObject=self.getActiveObject() activeObjectQueue=self.Res.activeQ
activeObjectQueue=activeObject.getActiveObjectQueue()
activeEntity=activeObjectQueue[0] activeEntity=activeObjectQueue[0]
# if the machine returns from an failure while processing an entity # if the machine returns from an failure while processing an entity
if not activeObject.waitToDispose: if not self.waitToDispose:
# use the timers to count the time that Machine is down and related # use the timers to count the time that Machine is down and related
self.downTimeProcessingCurrentEntity+=now()-self.breakTime # count the time that Machine is down while processing this Entity self.downTimeProcessingCurrentEntity+=now()-self.breakTime # count the time that Machine is down while processing this Entity
self.downTimeInCurrentEntity+=now()-self.breakTime # count the time that Machine is down while on currentEntity self.downTimeInCurrentEntity+=now()-self.breakTime # count the time that Machine is down while on currentEntity
self.timeLastFailureEnded=now() # set the timeLastFailureEnded self.timeLastFailureEnded=now() # set the timeLastFailureEnded
self.failureTimeInCurrentEntity+=now()-self.breakTime # dummy variable keeping track of the failure time self.failureTimeInCurrentEntity+=now()-self.breakTime # dummy variable keeping track of the failure time
# output to trace that the Machine self.objName was passivated for the current failure time # output to trace that the Machine self.objName was passivated for the current failure time
self.outputTrace(self.getActiveObjectQueue()[0].name, "passivated in "+self.objName+" for "+str(now()-self.breakTime)) self.outputTrace(activeObjectQueue[0].name, "passivated in "+self.objName+" for "+str(now()-self.breakTime))
# when a machine returns from failure while trying to deliver an entity # when a machine returns from failure while trying to deliver an entity
else: else:
# count the failure while on current entity time with failureTime variable # count the failure while on current entity time with failureTime variable
...@@ -579,41 +577,37 @@ class Machine(CoreObject): ...@@ -579,41 +577,37 @@ class Machine(CoreObject):
# that will give the entity. # that will give the entity.
# ======================================================================= # =======================================================================
def canAccept(self, callerObject=None): def canAccept(self, callerObject=None):
# get active and giver objects activeObjectQueue=self.Res.activeQ
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
# if we have only one predecessor just check if there is a place and the machine is up # if we have only one predecessor just check if there is a place and the machine is up
# this is done to achieve better (cpu) processing time # this is done to achieve better (cpu) processing time
# then we can also use it as a filter for a yield method # then we can also use it as a filter for a yield method
if(callerObject==None): if(callerObject==None):
if (activeObject.operatorPool!='None' and (any(type=='Load' for type in activeObject.multOperationTypeList)\ if (self.operatorPool!='None' and (any(type=='Load' for type in self.multOperationTypeList)\
or any(type=='Setup' for type in activeObject.multOperationTypeList))): or any(type=='Setup' for type in self.multOperationTypeList))):
return activeObject.operatorPool.checkIfResourceIsAvailable()\ return self.operatorPool.checkIfResourceIsAvailable()\
and activeObject.checkIfMachineIsUp()\ and self.checkIfMachineIsUp()\
and len(activeObjectQueue)<activeObject.capacity\ and len(activeObjectQueue)<self.capacity\
and not activeObject.entryIsAssignedTo() and not self.entryIsAssignedTo()
else: else:
return activeObject.checkIfMachineIsUp()\ return self.checkIfMachineIsUp()\
and len(activeObjectQueue)<activeObject.capacity\ and len(activeObjectQueue)<self.capacity\
and not activeObject.entryIsAssignedTo() and not self.entryIsAssignedTo()
thecaller=callerObject thecaller=callerObject
# return True ONLY if the length of the activeOjbectQue is smaller than # return True ONLY if the length of the activeOjbectQue is smaller than
# the object capacity, and the callerObject is not None but the giverObject # the object capacity, and the callerObject is not None but the giverObject
if (activeObject.operatorPool!='None' and (any(type=='Load' for type in activeObject.multOperationTypeList)\ if (self.operatorPool!='None' and (any(type=='Load' for type in self.multOperationTypeList)\
or any(type=='Setup' for type in activeObject.multOperationTypeList))): or any(type=='Setup' for type in self.multOperationTypeList))):
return activeObject.operatorPool.checkIfResourceIsAvailable()\ return self.operatorPool.checkIfResourceIsAvailable()\
and activeObject.checkIfMachineIsUp()\ and self.checkIfMachineIsUp()\
and len(activeObjectQueue)<activeObject.capacity\ and len(activeObjectQueue)<self.capacity\
and not activeObject.entryIsAssignedTo() and not self.entryIsAssignedTo()
else: else:
# the operator doesn't have to be present for the loading of the machine as the load operation # the operator doesn't have to be present for the loading of the machine as the load operation
# is not assigned to operators # is not assigned to operators
return activeObject.checkIfMachineIsUp()\ return self.checkIfMachineIsUp()\
and len(activeObjectQueue)<activeObject.capacity\ and len(activeObjectQueue)<self.capacity\
and (thecaller in activeObject.previous)\ and (thecaller in self.previous)\
and not activeObject.entryIsAssignedTo() and not self.entryIsAssignedTo()
# ======================================================================= # =======================================================================
# checks if the Machine can accept an entity and there is an entity in # checks if the Machine can accept an entity and there is an entity in
...@@ -621,22 +615,19 @@ class Machine(CoreObject): ...@@ -621,22 +615,19 @@ class Machine(CoreObject):
# also updates the giver to the one that is to be taken # also updates the giver to the one that is to be taken
# ======================================================================= # =======================================================================
def canAcceptAndIsRequested(self,callerObject=None): def canAcceptAndIsRequested(self,callerObject=None):
# get active and giver objects activeObjectQueue=self.Res.activeQ
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
# giverObject=self.getGiverObject()
giverObject=callerObject giverObject=callerObject
assert giverObject, 'there must be a caller for canAcceptAndIsRequested' assert giverObject, 'there must be a caller for canAcceptAndIsRequested'
# check if there is a place, the machine is up and the predecessor has an entity to dispose. if the machine has to compete # check if there is a place, the machine is up and the predecessor has an entity to dispose. if the machine has to compete
# for an Operator that loads the entities onto it check if the predecessor if blocked by an other Machine. if not then the machine # for an Operator that loads the entities onto it check if the predecessor if blocked by an other Machine. if not then the machine
# has to block the predecessor giverObject to avoid conflicts with other competing machines # has to block the predecessor giverObject to avoid conflicts with other competing machines
if (activeObject.operatorPool!='None' and (any(type=='Load' for type in activeObject.multOperationTypeList))): if (self.operatorPool!='None' and (any(type=='Load' for type in self.multOperationTypeList))):
if giverObject.haveToDispose(activeObject): if giverObject.haveToDispose(self):
if activeObject.checkOperator()\ if self.checkOperator()\
and activeObject.checkIfActive() and len(activeObjectQueue)<activeObject.capacity: and self.checkIfActive() and len(activeObjectQueue)<self.capacity:
if not giverObject.exitIsAssignedTo(): if not giverObject.exitIsAssignedTo():
giverObject.assignExitTo(activeObject) giverObject.assignExitTo(self)
elif giverObject.exitIsAssignedTo()!=activeObject: elif giverObject.exitIsAssignedTo()!=self:
return False return False
return True return True
else: else:
...@@ -645,11 +636,11 @@ class Machine(CoreObject): ...@@ -645,11 +636,11 @@ class Machine(CoreObject):
# the operator performs no load and the entity is received by the machine while there is # the operator performs no load and the entity is received by the machine while there is
# no need for operators presence. The operator needs to be present only where the load Type # no need for operators presence. The operator needs to be present only where the load Type
# operation is assigned # operation is assigned
if activeObject.checkIfActive() and len(activeObjectQueue)<activeObject.capacity\ if self.checkIfActive() and len(activeObjectQueue)<self.capacity\
and giverObject.haveToDispose(activeObject): and giverObject.haveToDispose(self):
if not giverObject.exitIsAssignedTo(): if not giverObject.exitIsAssignedTo():
giverObject.assignExitTo(activeObject) giverObject.assignExitTo(self)
elif giverObject.exitIsAssignedTo()!=activeObject: elif giverObject.exitIsAssignedTo()!=self:
return False return False
return True return True
...@@ -657,27 +648,25 @@ class Machine(CoreObject): ...@@ -657,27 +648,25 @@ class Machine(CoreObject):
# return whether Load or setup Requested # return whether Load or setup Requested
#=========================================================================== #===========================================================================
def isLoadRequested(self): def isLoadRequested(self):
activeObject=self.getActiveObject() return any(type=='Load' or type=='Setup' for type in self.multOperationTypeList)
return any(type=='Load' or type=='Setup' for type in activeObject.multOperationTypeList)
# ======================================================================= # =======================================================================
# to be called by canAcceptAndIsRequested and check for the operator # to be called by canAcceptAndIsRequested and check for the operator
# ======================================================================= # =======================================================================
def checkOperator(self,callerObject=None): def checkOperator(self,callerObject=None):
activeObject=self.getActiveObject()
mayProceed=False mayProceed=False
if activeObject.operatorPool.operators: if self.operatorPool.operators:
# flag notifying that there is operator assigned to the actievObject # flag notifying that there is operator assigned to the actievObject
self.assignedOperator=False self.assignedOperator=False
# the operators operating the station # the operators operating the station
operators=activeObject.operatorPool.operators operators=self.operatorPool.operators
if activeObject.operatorPool.checkIfResourceIsAvailable(): if self.operatorPool.checkIfResourceIsAvailable():
for operator in [x for x in operators if x.checkIfResourceIsAvailable()]: for operator in [x for x in operators if x.checkIfResourceIsAvailable()]:
# if there are operators available not assigned to the station then the station may proceed signalling the Router # if there are operators available not assigned to the station then the station may proceed signalling the Router
if not operator.isAssignedTo(): if not operator.isAssignedTo():
mayProceed=True mayProceed=True
# if there are operators assigned to the station then proceed without invoking the Router # if there are operators assigned to the station then proceed without invoking the Router
elif operator.isAssignedTo()==activeObject: elif operator.isAssignedTo()==self:
self.assignedOperator=True self.assignedOperator=True
break break
return mayProceed or self.assignedOperator return mayProceed or self.assignedOperator
...@@ -688,41 +677,38 @@ class Machine(CoreObject): ...@@ -688,41 +677,38 @@ class Machine(CoreObject):
# get an entity from the giver # get an entity from the giver
# ======================================================================= # =======================================================================
def getEntity(self): def getEntity(self):
activeObject=self.getActiveObject()
activeEntity=CoreObject.getEntity(self) # run the default method activeEntity=CoreObject.getEntity(self) # run the default method
# after the machine receives an entity, it must be removed from the pendingEntities list # after the machine receives an entity, it must be removed from the pendingEntities list
from Globals import G from Globals import G
if activeEntity in G.pendingEntities: if G.Router:
G.pendingEntities.remove(activeEntity) if activeEntity in G.pendingEntities:
G.pendingEntities.remove(activeEntity)
return activeEntity return activeEntity
# ======================================================================= # =======================================================================
# removes an entity from the Machine # removes an entity from the Machine
# ======================================================================= # =======================================================================
def removeEntity(self, entity=None): def removeEntity(self, entity=None):
activeObject=self.getActiveObject()
activeEntity=CoreObject.removeEntity(self, entity) # run the default method activeEntity=CoreObject.removeEntity(self, entity) # run the default method
activeObject.waitToDispose=False # update the waitToDispose flag self.waitToDispose=False # update the waitToDispose flag
# if the Machine canAccept then signal a giver # if the Machine canAccept then signal a giver
if activeObject.canAccept(): if self.canAccept():
self.printTrace(self.id, attemptSignalGiver='(removeEntity)') # self.printTrace(self.id, attemptSignalGiver='(removeEntity)')
activeObject.signalGiver() self.signalGiver()
return activeEntity return activeEntity
# ======================================================================= # =======================================================================
# checks if the Machine can dispose an entity to the following object # checks if the Machine can dispose an entity to the following object
# ======================================================================= # =======================================================================
def haveToDispose(self, callerObject=None): def haveToDispose(self, callerObject=None):
# get active and the receiver object activeObjectQueue=self.Res.activeQ
activeObject=self.getActiveObject()
activeObjectQueue=self.getActiveObjectQueue()
#if we have only one successor just check if machine waits to dispose and also is up #if we have only one successor just check if machine waits to dispose and also is up
# this is done to achieve better (cpu) processing time # this is done to achieve better (cpu) processing time
if(len(activeObject.next)==1 or callerObject==None): if(len(self.next)==1 or callerObject==None):
return len(activeObjectQueue)>0 and activeObject.waitToDispose and activeObject.checkIfActive() return len(activeObjectQueue)>0 and self.waitToDispose and self.checkIfActive()
thecaller=callerObject thecaller=callerObject
return len(activeObjectQueue)>0 and activeObject.waitToDispose\ return len(activeObjectQueue)>0 and self.waitToDispose\
and activeObject.checkIfActive() and (thecaller in activeObject.next) and self.checkIfActive() and (thecaller in self.next)
# ======================================================================= # =======================================================================
# calculates the setup time # calculates the setup time
...@@ -741,28 +727,26 @@ class Machine(CoreObject): ...@@ -741,28 +727,26 @@ class Machine(CoreObject):
# find candidate operators within the free operators # find candidate operators within the free operators
#=========================================================================== #===========================================================================
def findCandidateOperator(self): def findCandidateOperator(self):
activeObject=self.getActiveObject()
# TODO: this way no sorting is performed # TODO: this way no sorting is performed
# find an available operator # find an available operator
candidateOperator=activeObject.operatorPool.findAvailableOperator() candidateOperator=self.operatorPool.findAvailableOperator()
# append the station into its candidateStations # append the station into its candidateStations
candidateOperator.candidateStations.append(activeObject) candidateOperator.candidateStations.append(self)
return candidateOperator return candidateOperator
#=========================================================================== #===========================================================================
# checks whether the entity can proceed to a successor object # checks whether the entity can proceed to a successor object
#=========================================================================== #===========================================================================
def canDeliver(self, entity=None): def canDeliver(self, entity=None):
activeObject=self.getActiveObject() assert self.isInActiveQueue(entity), entity.id +' not in the internalQueue of'+ self.id
assert activeObject.isInActiveQueue(entity), entity.id +' not in the internalQueue of'+ activeObject.id
activeEntity=entity activeEntity=entity
from Globals import G from Globals import G
router = G.Router router = G.Router
# 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 activeObject in router.pendingMachines: if self in router.pendingMachines:
activeEntity.proceed=True activeEntity.proceed=True
activeEntity.candidateReceivers.append(activeObject) activeEntity.candidateReceivers.append(self)
return True return True
return False return False
......
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