Broker now operates with events

parent 96b330f0
...@@ -318,8 +318,8 @@ class CoreObject(Process): ...@@ -318,8 +318,8 @@ class CoreObject(Process):
activeObject.receiver=activeObject.selectReceiver(possibleReceivers) activeObject.receiver=activeObject.selectReceiver(possibleReceivers)
activeObject.receiver.giver=activeObject activeObject.receiver.giver=activeObject
#=================================================================== #===================================================================
# TESTING # # TESTING
# print now(), self.id, 'signaling receiver', self.receiver.id # print now(), self.id,' '*50, 'signaling receiver', self.receiver.id
#=================================================================== #===================================================================
activeObject.receiver.isRequested.signal(activeObject) activeObject.receiver.isRequested.signal(activeObject)
return True return True
...@@ -360,8 +360,8 @@ class CoreObject(Process): ...@@ -360,8 +360,8 @@ class CoreObject(Process):
activeObject.giver=activeObject.selectGiver(possibleGivers) activeObject.giver=activeObject.selectGiver(possibleGivers)
activeObject.giver.receiver=activeObject activeObject.giver.receiver=activeObject
#=================================================================== #===================================================================
# TESTING # # TESTING
# print now(), self.id, 'signaling giver', self.giver.id # print now(), self.id,' '*50, 'signaling giver', self.giver.id
#=================================================================== #===================================================================
activeObject.giver.canDispose.signal(activeObject) activeObject.giver.canDispose.signal(activeObject)
return True return True
......
...@@ -53,29 +53,31 @@ class ObjectInterruption(Process): ...@@ -53,29 +53,31 @@ class ObjectInterruption(Process):
# ======================================================================= # =======================================================================
# hand in the control to the objectIterruption.run # hand in the control to the objectIterruption.run
# to be called by the machine # to be called by the machine
# TODO: consider removing this method,
# signalling can be done via Machine request/releaseOperator
# ======================================================================= # =======================================================================
def invoke(self): def invoke(self):
self.call=True self.brokerIsCalled.signal(now())
# ======================================================================= # # =======================================================================
# return control to the Machine.run # # return control to the Machine.run
# ======================================================================= # # =======================================================================
def exit(self): # def exit(self):
self.call=False # self.call=False
# ======================================================================= # # =======================================================================
# call the objectInterruption # # call the objectInterruption
# filter for object interruption - yield waituntil isCalled # # filter for object interruption - yield waituntil isCalled
# ======================================================================= # # =======================================================================
def isCalled(self): # def isCalled(self):
return self.call # return self.call
# ======================================================================= # # =======================================================================
# the objectIterruption returns control to machine.Run # # the objectIterruption returns control to machine.Run
# filter for Machine - yield request/release operator # # filter for Machine - yield request/release operator
# ======================================================================= # # =======================================================================
def isSet(self): # def isSet(self):
return not self.call # return not self.call
#=========================================================================== #===========================================================================
# outputs data to "output.xls" # outputs data to "output.xls"
...@@ -110,7 +112,7 @@ class ObjectInterruption(Process): ...@@ -110,7 +112,7 @@ class ObjectInterruption(Process):
# reactivate the victim # reactivate the victim
#=========================================================================== #===========================================================================
def reactivateVictim(self): def reactivateVictim(self):
self.victim.interruptionEnd.signal(self.victim) self.victim.interruptionEnd.signal(now())
# reactivate(self.victim) # reactivate(self.victim)
#=========================================================================== #===========================================================================
......
...@@ -26,9 +26,9 @@ Created on 27 Nov 2013 ...@@ -26,9 +26,9 @@ Created on 27 Nov 2013
Models an Interruption that handles the operating of a Station by an ObjectResource Models an Interruption that handles the operating of a Station by an ObjectResource
''' '''
from SimPy.Simulation import Process, Resource from SimPy.Simulation import Process, Resource, SimEvent
from ObjectInterruption import ObjectInterruption from ObjectInterruption import ObjectInterruption
from SimPy.Simulation import waituntil, now, hold, request, release from SimPy.Simulation import waituntil, now, hold, request, release, waitevent
# =========================================================================== # ===========================================================================
# Class that handles the Operator Behavior # Class that handles the Operator Behavior
...@@ -47,6 +47,10 @@ class Broker(ObjectInterruption): ...@@ -47,6 +47,10 @@ class Broker(ObjectInterruption):
self.timeOperationStarted = 0 self.timeOperationStarted = 0
self.timeLastOperationEnded = 0 self.timeLastOperationEnded = 0
self.timeWaitForOperatorStarted=0 self.timeWaitForOperatorStarted=0
# Broker events
self.brokerIsCalled=SimEvent('brokerIsCalled')
self.victimQueueIsEmpty=SimEvent('victimQueueIsEmpty')
self.resourceAvailable=SimEvent('resourceAvailable')
#=========================================================================== #===========================================================================
# the initialize method # the initialize method
...@@ -62,25 +66,27 @@ class Broker(ObjectInterruption): ...@@ -62,25 +66,27 @@ class Broker(ObjectInterruption):
# ======================================================================= # =======================================================================
def run(self): def run(self):
while 1: while 1:
yield waituntil,self,self.isCalled # wait until the broker is called # TODO: add new broker event - brokerIsCalled
yield waitevent, self, self.brokerIsCalled
assert self.brokerIsCalled.signalparam==now(), 'the broker should be granted control instantly'
# ======= request a resource # ======= request a resource
if self.victim.isOperated()\ if self.victim.isOperated()\
and any(type=="Load" or type=="Setup" or type=="Processing"\ and any(type=='Load' or type=='Setup' or type=='Processing'\
for type in self.victim.multOperationTypeList): for type in self.victim.multOperationTypeList):
# 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()
# # update the currentObject of the operatorPool # TODO: cannot wait till the operatorPool has available resources.
# self.victim.operatorPool.currentObject = self.victim # They are supposed to be available for the Broker to be called
# wait until a resource is available if not self.victim.operatorPool.checkIfResourceIsAvailable():
yield waituntil, self, self.victim.operatorPool.checkIfResourceIsAvailable yield waitevent, self, self.resourceAvailable
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()
yield request,self,self.victim.operatorPool.getResource(self.victim.currentOperator) yield request, self, self.victim.operatorPool.getResource(self.victim.currentOperator)
#=============================================================== #===============================================================
# # TESTING # # TESTING
# print now(), self.victim.currentOperator.objName, 'started work in ', self.victim.id # print now(), self.victim.currentOperator.objName, 'started work in ', self.victim.id
#=============================================================== #===============================================================
# self.victim.totalTimeWaitingForOperator+=now()-self.timeWaitForOperatorStarted
# clear the timeWaitForOperatorStarted variable # clear the timeWaitForOperatorStarted variable
self.timeWaitForOperatorStarted = 0 self.timeWaitForOperatorStarted = 0
# update the time that the operation started # update the time that the operation started
...@@ -89,22 +95,107 @@ class Broker(ObjectInterruption): ...@@ -89,22 +95,107 @@ class Broker(ObjectInterruption):
self.victim.currentOperator.timeLastOperationStarted=now() self.victim.currentOperator.timeLastOperationStarted=now()
# ======= release a resource # ======= release a resource
elif not self.victim.isOperated(): elif not self.victim.isOperated():
self.victim.currentOperator.totalWorkingTime+=now()-self.victim.currentOperator.timeLastOperationStarted self.victim.currentOperator.totalWorkingTime+=now()-self.victim.currentOperator.timeLastOperationStarted
# TODO: cannot be implemented at the moment as the Machine first releases the operator and then
# signals the receiver when the removeEntity signals the victimQueueIsEmpty
# if the victim releasing the operator has receiver # if the victim releasing the operator has receiver
if self.victim.receiver: # if self.victim.receiver:
# if the following object is not of type Machine # # if the following object is not of type Machine
if self.victim.receiver.type!='Machine': # if self.victim.receiver.type!='Machine':
# if the processingType is 'Processing' and not only 'Load' or 'Setup' # # if the processingType is 'Processing' and not only 'Load' or 'Setup'
if any(type=='Processing' for type in self.victim.multOperationTypeList): # if any(type=='Processing' for type in self.victim.multOperationTypeList):
# wait until the victim has released the entity it was processing # # wait until the victim has released the entity it was processing
yield waituntil, self, self.victim.activeQueueIsEmpty # # TODO: add new event, to be signalled from the Machine removeEntity
# yield waitevent, self, self.victimQueueIsEmpty
# assert self.victimQueueIsEmpty.signalparam==now(), 'the broker should be granted control instantly'
#self.victim.outputTrace(self.victim.currentOperator.objName, "left "+ self.victim.objName) #self.victim.outputTrace(self.victim.currentOperator.objName, "left "+ self.victim.objName)
yield release,self,self.victim.operatorPool.getResource(self.victim.currentOperator) yield release,self,self.victim.operatorPool.getResource(self.victim.currentOperator)
# TODO: somehow signal the other brokers waiting for the same operators that they are now free
from Globals import G
candidateMachines=[]
pendingMachines=[]
for operatorpool in G.OperatorPoolsList:
if self.victim.currentOperator in operatorpool.operators:
for machine in operatorpool.coreObjects:
if machine.broker.timeWaitForOperatorStarted:
candidateMachines.append(machine)
if machine.canAccept() and any(type=='Load' for type in machine.multOperationTypeList):
#===============================================
# # TESTING
# print now(), self.victim.id, 'broker signalling', machine.id, 'loadOperatorAvailable'
#===============================================
machine.loadOperatorAvailable.signal(now())
if candidateMachines:
maxTimeWaiting=0
receiver=None
for machine in candidateMachines:
timeWaiting=now()-machine.broker.timeWaitForOperatorStarted
if(timeWaiting>maxTimeWaiting or maxTimeWaiting==0):
maxTimeWaiting=timeWaiting
receiver=machine
#===========================================================
# # TESTING
# print now(), self.victim.id, 'broker signalling', machine.id, 'resourceAvailable'
#===========================================================
receiver.broker.resourceAvailable.signal(now())
#===============================================================
# # TESTING
# print now(), self.victim.currentOperator.objName, 'released', self.victim.id
#===============================================================
# the victim current operator must be cleared after the operator is released # the victim current operator must be cleared after the operator is released
self.timeLastOperationEnded = now() self.timeLastOperationEnded = now()
self.victim.currentOperator = None self.victim.currentOperator = None
else: else:
pass pass
# return the control the machine.run # TODO: exit method can perform the signalling
self.exit() # TODO: the victim must have a new event brokerIsSet
self.victim.brokerIsSet.signal(now())
# yield waituntil,self,self.isCalled # wait until the broker is called
# # ======= request a resource
# if self.victim.isOperated()\
# and any(type=="Load" or type=="Setup" or type=="Processing"\
# for type in self.victim.multOperationTypeList):
# # update the time that the station is waiting for the operator
# self.timeWaitForOperatorStarted=now()
# # # update the currentObject of the operatorPool
# # self.victim.operatorPool.currentObject = self.victim
# # wait until a resource is available
# yield waituntil, self, self.victim.operatorPool.checkIfResourceIsAvailable
# # set the available resource as the currentOperator
# self.victim.currentOperator=self.victim.operatorPool.findAvailableOperator()
# yield request,self,self.victim.operatorPool.getResource(self.victim.currentOperator)
# #===============================================================
# # # TESTING
# # print now(), self.victim.currentOperator.objName, 'started work in ', self.victim.id
# #===============================================================
# # self.victim.totalTimeWaitingForOperator+=now()-self.timeWaitForOperatorStarted
# # clear the timeWaitForOperatorStarted variable
# self.timeWaitForOperatorStarted = 0
# # update the time that the operation started
# self.timeOperationStarted = now()
# self.victim.outputTrace(self.victim.currentOperator.objName, "started work in "+ self.victim.objName)
# self.victim.currentOperator.timeLastOperationStarted=now()
# # ======= release a resource
# elif not self.victim.isOperated():
# self.victim.currentOperator.totalWorkingTime+=now()-self.victim.currentOperator.timeLastOperationStarted
# # if the victim releasing the operator has receiver
# if self.victim.receiver:
# # if the following object is not of type Machine
# if self.victim.receiver.type!='Machine':
# # if the processingType is 'Processing' and not only 'Load' or 'Setup'
# if any(type=='Processing' for type in self.victim.multOperationTypeList):
# # wait until the victim has released the entity it was processing
# yield waituntil, self, self.victim.activeQueueIsEmpty
# #self.victim.outputTrace(self.victim.currentOperator.objName, "left "+ self.victim.objName)
# yield release,self,self.victim.operatorPool.getResource(self.victim.currentOperator)
# # the victim current operator must be cleared after the operator is released
# self.timeLastOperationEnded = now()
# self.victim.currentOperator = None
# else:
# pass
# # return the control the machine.run
# self.exit()
\ No newline at end of file
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