Machine now communicates with Broker via events. Machine waits for isRequested...

Machine now communicates with Broker via events. Machine waits for isRequested signal to getEntity. Can also get an entity after a loadOperatorAvailable event in case it could not getEntity due to resources lack
parent 1181d837
...@@ -97,6 +97,8 @@ class Machine(CoreObject): ...@@ -97,6 +97,8 @@ class Machine(CoreObject):
id = id+'_OP' id = id+'_OP'
name=self.objName+'_operatorPool' name=self.objName+'_operatorPool'
self.operatorPool=OperatorPool(id, name, operatorsList=operatorPool) self.operatorPool=OperatorPool(id, name, operatorsList=operatorPool)
from Globals import G
G.OperatorPoolsList.append(self.operatorPool)
elif(type(operatorPool) is OperatorPool): elif(type(operatorPool) is OperatorPool):
self.operatorPool=operatorPool self.operatorPool=operatorPool
else: else:
...@@ -147,7 +149,14 @@ class Machine(CoreObject): ...@@ -147,7 +149,14 @@ class Machine(CoreObject):
# flags used for preemption purposes # flags used for preemption purposes
self.isPreemptive=isPreemptive self.isPreemptive=isPreemptive
self.resetOnPreemption=resetOnPreemption self.resetOnPreemption=resetOnPreemption
# event used by the router # events used by the broker
self.brokerIsSet=SimEvent('brokerIsSet')
# this event is generated every time an operator is requested by machine for Load operation type.
# if the machine has not succeeded in getting an entity due to the resource absence
# and waits for the next event to get the entity,
# then it must be signalled that the operator is now available
self.loadOperatorAvailable=SimEvent('loadOperatorAvailable')
self.routerCycleOver=SimEvent('routerCycleOver') self.routerCycleOver=SimEvent('routerCycleOver')
# ======================================================================= # =======================================================================
...@@ -213,24 +222,25 @@ class Machine(CoreObject): ...@@ -213,24 +222,25 @@ class Machine(CoreObject):
self.initialSignalReceiver() self.initialSignalReceiver()
# execute all through simulation time # execute all through simulation time
while 1: while 1:
# waitEvent isRequested or interruption start # waitEvent isRequested or an interruptionEnd
while 1: while 1:
yield waitevent, self, [self.isRequested, self.interruptionStart] yield waitevent, self, [self.isRequested, self.interruptionEnd, self.loadOperatorAvailable]
# if the machine is interrupted # if the machine can accept an entity and one predecessor requests it continue with receiving the entity
if self.interruptionStart.signalparam==now(): if self.isRequested.signalparam:
# wait until the interruption is ended assert self.isRequested.signalparam==self.giver, 'the giver is not the requestingObject'
yield waitevent, self, self.interruptionEnd # interruptionEnd to be triggered by ObjectInterruption self.isRequested.signalparam=None
assert self==self.interruptionEnd.signalparam, 'the victim of the failure is not the object that received it' break
# if an interruption caused the control to be taken by the machine
if self.interruptionEnd.signalparam==now():
# and signal the Giver, otherwise wait until it is requested # and signal the Giver, otherwise wait until it is requested
if self.signalGiver(): if self.signalGiver():
break break
# if the machine can accept an entity and one predecessor requests it continuew with receiving the entity # if an operator was rendered available while it was needed by the machine to proceed with getting
else: elif self.loadOperatorAvailable.signalparam==now():
break # try to signal the giver, otherwise wait until it is requested
if self.signalGiver():
break
# TODO: maybe here have to assigneExit of the giver and add self to operator activeCallers list # TODO: maybe here have to assigneExit of the giver and add self to operator activeCallers list
requestingObject=self.isRequested.signalparam
assert requestingObject==self.giver, 'the giver is not the requestingObject'
#=============================================================================== #===============================================================================
# # reset the canProceedWithGetEntity flag # # reset the canProceedWithGetEntity flag
# self.canProceedWithGetEntity=False # self.canProceedWithGetEntity=False
...@@ -264,41 +274,41 @@ class Machine(CoreObject): ...@@ -264,41 +274,41 @@ class Machine(CoreObject):
self.setupTimeCurrentEntity = 0 self.setupTimeCurrentEntity = 0
#=========================================================================== #===========================================================================
# # ======= request a resource # ======= request a resource
# if(self.operatorPool!="None") and any(type=='Load' for type in self.multOperationTypeList): if(self.operatorPool!="None") and any(type=='Load' for type in self.multOperationTypeList):
# # when it's ready to accept (canAcceptAndIsRequested) then inform the broker # when it's ready to accept (canAcceptAndIsRequested) then inform the broker
# # machines waits to be operated (waits for the operator) # machines waits to be operated (waits for the operator)
# self.requestOperator() self.requestOperator()
# self.timeWaitForLoadOperatorStarted = now() self.timeWaitForLoadOperatorStarted = now()
# # wait until the Broker has waited times equal to loadTime (if any) # wait until the Broker has waited times equal to loadTime (if any)
# yield waituntil, self, self.broker.isSet yield waitevent, self, self.brokerIsSet
# self.timeWaitForLoadOperatorEnded = now() self.timeWaitForLoadOperatorEnded = now()
# self.loadOperatorWaitTimeCurrentEntity += self.timeWaitForLoadOperatorEnded-self.timeWaitForLoadOperatorStarted self.loadOperatorWaitTimeCurrentEntity += self.timeWaitForLoadOperatorEnded-self.timeWaitForLoadOperatorStarted
# self.totalTimeWaitingForLoadOperator += self.loadOperatorWaitTimeCurrentEntity self.totalTimeWaitingForLoadOperator += self.loadOperatorWaitTimeCurrentEntity
#
# # ======= Load the machine if the Load is defined as one of the Operators' operation types # ======= Load the machine if the Load is defined as one of the Operators' operation types
# if any(type=="Load" for type in self.multOperationTypeList) and self.isOperated(): if any(type=="Load" for type in self.multOperationTypeList) and self.isOperated():
# self.timeLoadStarted = now() self.timeLoadStarted = now()
# yield hold,self,self.calculateLoadTime() yield hold,self,self.calculateLoadTime()
# # TODO: if self.interrupted(): There is the issue of failure during the Loading # TODO: if self.interrupted(): There is the issue of failure during the Loading
# self.timeLoadEnded = now() self.timeLoadEnded = now()
# self.loadTimeCurrentEntity = self.timeLoadEnded-self.timeLoadStarted self.loadTimeCurrentEntity = self.timeLoadEnded-self.timeLoadStarted
# self.totalLoadTime += self.loadTimeCurrentEntity self.totalLoadTime += self.loadTimeCurrentEntity
#
# # ======= release a resource if the only operation type is Load # ======= release a resource if the only operation type is Load
# if (self.operatorPool!="None")\ if (self.operatorPool!="None")\
# and any(type=="Load" for type in self.multOperationTypeList)\ and any(type=="Load" for type in self.multOperationTypeList)\
# and not (any(type=="Processing" for type in self.multOperationTypeList)\ and not (any(type=="Processing" for type in self.multOperationTypeList)\
# or any(type=="Setup" for type in self.multOperationTypeList))\ or any(type=="Setup" for type in self.multOperationTypeList))\
# and self.isOperated(): and self.isOperated():
# # after getting the entity release the operator # after getting the entity release the operator
# # machine has to release the operator # machine has to release the operator
# self.releaseOperator() self.releaseOperator()
# # wait until the Broker has finished processing # wait until the Broker has finished processing
# yield waituntil, self, self.broker.isSet yield waitevent, self, self.brokerIsSet
#
# # TODO: reset the requestinEntity before receiving the currentEntity # TODO: reset the requestinEntity before receiving the currentEntity
# self.requestingEntity=None self.requestingEntity=None
#=========================================================================== #===========================================================================
# get the entity # get the entity
# TODO: if there was loading time then we must solve the problem of getting an entity # TODO: if there was loading time then we must solve the problem of getting an entity
...@@ -309,19 +319,19 @@ class Machine(CoreObject): ...@@ -309,19 +319,19 @@ class Machine(CoreObject):
# the canAcceptAndIsRequested method checks only in case of Load type of operation # the canAcceptAndIsRequested method checks only in case of Load type of operation
#=========================================================================== #===========================================================================
# # ======= request a resource if it is not already assigned an Operator # ======= request a resource if it is not already assigned an Operator
# if(self.operatorPool!="None")\ if(self.operatorPool!="None")\
# and (any(type=="Processing" for type in self.multOperationTypeList)\ and (any(type=="Processing" for type in self.multOperationTypeList)\
# or any(type=="Setup" for type in self.multOperationTypeList))\ or any(type=="Setup" for type in self.multOperationTypeList))\
# and not self.isOperated(): and not self.isOperated():
# # when it's ready to accept (canAcceptAndIsRequested) then inform the broker # when it's ready to accept (canAcceptAndIsRequested) then inform the broker
# # machines waits to be operated (waits for the operator) # machines waits to be operated (waits for the operator)
# self.requestOperator() self.requestOperator()
# self.timeWaitForOperatorStarted = now() self.timeWaitForOperatorStarted = now()
# # wait until the Broker has waited times equal to loadTime (if any) # wait until the Broker has waited times equal to loadTime (if any)
# yield waituntil, self, self.broker.isSet yield waitevent, self, self.brokerIsSet
# self.timeWaitForOperatorEnded = now() self.timeWaitForOperatorEnded = now()
# self.operatorWaitTimeCurrentEntity += self.timeWaitForOperatorEnded-self.timeWaitForOperatorStarted self.operatorWaitTimeCurrentEntity += self.timeWaitForOperatorEnded-self.timeWaitForOperatorStarted
#=========================================================================== #===========================================================================
# variables dedicated to hold the processing times, the time when the Entity entered, # variables dedicated to hold the processing times, the time when the Entity entered,
...@@ -330,51 +340,51 @@ class Machine(CoreObject): ...@@ -330,51 +340,51 @@ class Machine(CoreObject):
self.tinM=self.totalProcessingTimeInCurrentEntity # timer to hold the processing time left self.tinM=self.totalProcessingTimeInCurrentEntity # timer to hold the processing time left
#=============================================================================== #===============================================================================
# # ======= setup the machine if the Setup is defined as one of the Operators' operation types # ======= setup the machine if the Setup is defined as one of the Operators' operation types
# # in plantSim the setup is performed when the machine has to process a new type of Entity and only once # in plantSim the setup is performed when the machine has to process a new type of Entity and only once
# if any(type=="Setup" for type in self.multOperationTypeList) and self.isOperated(): if any(type=="Setup" for type in self.multOperationTypeList) and self.isOperated():
# self.timeSetupStarted = now() self.timeSetupStarted = now()
# yield hold,self,self.calculateSetupTime() yield hold,self,self.calculateSetupTime()
# # TODO: if self.interrupted(): There is the issue of failure during the setup # TODO: if self.interrupted(): There is the issue of failure during the setup
# self.timeSetupEnded = now() self.timeSetupEnded = now()
# self.setupTimeCurrentEntity = self.timeSetupEnded-self.timeSetupStarted self.setupTimeCurrentEntity = self.timeSetupEnded-self.timeSetupStarted
# self.totalSetupTime += self.setupTimeCurrentEntity self.totalSetupTime += self.setupTimeCurrentEntity
#
# # setup is performed only when setup is set in Machines multOperationTypeList # setup is performed only when setup is set in Machines multOperationTypeList
# # TODO: This must be also performed when no such operation is defined for the operator # TODO: This must be also performed when no such operation is defined for the operator
# # but setupTime is given for the entity to be processed # but setupTime is given for the entity to be processed
# # try: # try:
# # if self.setupTime and not any(type=="Setup" for type in self.multOperationTypeList): # if self.setupTime and not any(type=="Setup" for type in self.multOperationTypeList):
# # #=============================================================== # #===============================================================
# # # testing # # testing
# # if self.id=='MILL1' or self.id=='MILL2': # if self.id=='MILL1' or self.id=='MILL2':
# # print ' ', now(), self.id, 'auto-setup' # print ' ', now(), self.id, 'auto-setup'
# # #=============================================================== # #===============================================================
# # self.timeSetupStarted = now() # self.timeSetupStarted = now()
# # yield hold,self,self.calculateSetupTime() # yield hold,self,self.calculateSetupTime()
# # #=========================================================== # #===========================================================
# # # testing # # testing
# # if self.id=='MILL1' or self.id=='MILL2': # if self.id=='MILL1' or self.id=='MILL2':
# # print ' ', now() # print ' ', now()
# # #=========================================================== # #===========================================================
# # # TODO: if self.interrupted(): There is the issue of failure during the setup # # TODO: if self.interrupted(): There is the issue of failure during the setup
# # self.timeSetupEnded = now() # self.timeSetupEnded = now()
# # self.setupTimeCurrentEntity = self.timeSetupEnded-self.timeSetupStarted # self.setupTimeCurrentEntity = self.timeSetupEnded-self.timeSetupStarted
# # self.totalSetupTime += self.setupTimeCurrentEntity # self.totalSetupTime += self.setupTimeCurrentEntity
# # except: # except:
# # pass # pass
#
# # ======= release a resource if the only operation type is Setup # ======= release a resource if the only operation type is Setup
# if (self.operatorPool!="None")\ if (self.operatorPool!="None")\
# and self.isOperated()\ and self.isOperated()\
# and (any(type=="Setup" for type in self.multOperationTypeList)\ and (any(type=="Setup" for type in self.multOperationTypeList)\
# or any(type=="Load" for type in self.multOperationTypeList))\ or any(type=="Load" for type in self.multOperationTypeList))\
# and not any(type=="Processing" for type in self.multOperationTypeList): and not any(type=="Processing" for type in self.multOperationTypeList):
# # after getting the entity release the operator # after getting the entity release the operator
# # machine has to release the operator # machine has to release the operator
# self.releaseOperator() self.releaseOperator()
# # wait until the Broker has finished processing # wait until the Broker has finished processing
# yield waituntil, self, self.broker.isSet yield waitevent, self, self.brokerIsSet
#=============================================================================== #===============================================================================
# variables used to flag any interruptions and the end of the processing # variables used to flag any interruptions and the end of the processing
...@@ -398,18 +408,18 @@ class Machine(CoreObject): ...@@ -398,18 +408,18 @@ class Machine(CoreObject):
self.interruptionActions() # execute interruption actions self.interruptionActions() # execute interruption actions
#=========================================================================== #===========================================================================
# # =============== release the operator if there is interruption # =============== release the operator if there is interruption
# if (self.operatorPool!="None")\ if (self.operatorPool!="None")\
# and self.isOperated()\ and self.isOperated()\
# and any(type=="Processing" for type in self.multOperationTypeList): and any(type=="Processing" for type in self.multOperationTypeList):
# self.releaseOperator() self.releaseOperator()
# yield waituntil,self,self.broker.isSet yield waitevent,self,self.brokerIsSet
#=========================================================================== #===========================================================================
# if there is a failure in the machine or interruption due to preemption, it is passivated # if there is a failure in the machine or interruption due to preemption, it is passivated
# passivate the Machine for as long as there is no repair # passivate the Machine for as long as there is no repair
yield waitevent, self, self.interruptionEnd yield waitevent, self, self.interruptionEnd
assert self==self.interruptionEnd.signalparam, 'the victim of the failure is not the object that received it' assert now()==self.interruptionEnd.signalparam, 'the victim of the failure is not the object that received it'
self.postInterruptionActions() self.postInterruptionActions()
#=========================================================== #===========================================================
...@@ -419,15 +429,15 @@ class Machine(CoreObject): ...@@ -419,15 +429,15 @@ class Machine(CoreObject):
#=========================================================== #===========================================================
#=========================================================================== #===========================================================================
# # =============== request a resource after the repair # =============== request a resource after the repair
# if (self.operatorPool!="None")\ if (self.operatorPool!="None")\
# and any(type=="Processing" for type in self.multOperationTypeList)\ and any(type=="Processing" for type in self.multOperationTypeList)\
# and not self.interruption: and not self.interruption:
# self.timeWaitForOperatorStarted = now() self.timeWaitForOperatorStarted = now()
# self.requestOperator() self.requestOperator()
# yield waituntil,self,self.broker.isSet yield waitevent,self,self.brokerIsSet
# self.timeWaitForOperatorEnded = now() self.timeWaitForOperatorEnded = now()
# self.operatorWaitTimeCurrentEntity += self.timeWaitForOperatorEnded-self.timeWaitForOperatorStarted self.operatorWaitTimeCurrentEntity += self.timeWaitForOperatorEnded-self.timeWaitForOperatorStarted
#=========================================================================== #===========================================================================
# if no interruption occurred the processing in M1 is ended # if no interruption occurred the processing in M1 is ended
...@@ -455,12 +465,12 @@ class Machine(CoreObject): ...@@ -455,12 +465,12 @@ class Machine(CoreObject):
self.endProcessingActions() self.endProcessingActions()
#=========================================================================== #===========================================================================
# # =============== release resource after the end of processing # =============== release resource after the end of processing
# if (self.operatorPool!='None')\ if (self.operatorPool!='None')\
# and any(type=="Processing" for type in self.multOperationTypeList)\ and any(type=="Processing" for type in self.multOperationTypeList)\
# and not self.interruption: and not self.interruption:
# self.releaseOperator() self.releaseOperator()
# yield waituntil,self,self.broker.isSet yield waitevent,self,self.brokerIsSet
#=========================================================================== #===========================================================================
# signal the receiver that the activeObject has something to dispose of # signal the receiver that the activeObject has something to dispose of
...@@ -477,7 +487,7 @@ class Machine(CoreObject): ...@@ -477,7 +487,7 @@ class Machine(CoreObject):
# wait for the end of the interruption # wait for the end of the interruption
self.interruptionActions() # execute interruption actions self.interruptionActions() # execute interruption actions
yield waitevent, self, self.interruptionEnd # interruptionEnd to be triggered by ObjectInterruption yield waitevent, self, self.interruptionEnd # interruptionEnd to be triggered by ObjectInterruption
assert self==self.interruptionEnd.signalparam, 'the victim of the failure is not the object that received it' assert now()==self.interruptionEnd.signalparam, 'the victim of the failure is not the object that received it'
self.postInterruptionActions() self.postInterruptionActions()
#======================================================= #=======================================================
# TODO: not sure if this is required now # TODO: not sure if this is required now
...@@ -489,6 +499,9 @@ class Machine(CoreObject): ...@@ -489,6 +499,9 @@ class Machine(CoreObject):
if self.signalReceiver(): if self.signalReceiver():
break break
# TODO: in operated Machine, sometimes the giver is not signalled from the removeEntity method because there
# there was no operator available. In this case, by the time the operator is available again the Machine
# must receive the entity from the predecessor and thus the
# ======================================================================= # =======================================================================
# actions to be carried out when the processing of an Entity ends # actions to be carried out when the processing of an Entity ends
...@@ -707,8 +720,16 @@ class Machine(CoreObject): ...@@ -707,8 +720,16 @@ class Machine(CoreObject):
activeObject=self.getActiveObject() 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 activeObject.waitToDispose=False # update the waitToDispose flag
# if the Machine canAccept then signal a giver
if activeObject.canAccept(): if activeObject.canAccept():
activeObject.signalGiver() activeObject.signalGiver()
# if the Machine is operated then signal Broker that the internal queue is now empty
if activeObject.currentOperator:
#===================================================================
# # TESTING
# print now(), self.id, 'signalling broker that removed entity'
#===================================================================
activeObject.broker.victimQueueIsEmpty.signal(now())
return activeEntity return activeEntity
# ======================================================================= # =======================================================================
...@@ -720,7 +741,7 @@ class Machine(CoreObject): ...@@ -720,7 +741,7 @@ class Machine(CoreObject):
activeObjectQueue=self.getActiveObjectQueue() 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(activeObject.next)==1 or callerObject==None):
return len(activeObjectQueue)>0 and activeObject.waitToDispose and activeObject.checkIfActive() return len(activeObjectQueue)>0 and activeObject.waitToDispose and activeObject.checkIfActive()
thecaller=callerObject thecaller=callerObject
return len(activeObjectQueue)>0 and activeObject.waitToDispose\ return len(activeObjectQueue)>0 and activeObject.waitToDispose\
......
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