Router and Broker updated

parent 78428476
...@@ -26,9 +26,10 @@ Created on 27 Nov 2013 ...@@ -26,9 +26,10 @@ 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, SimEvent # from SimPy.Simulation import Process, Resource, SimEvent
import simpy
from ObjectInterruption import ObjectInterruption from ObjectInterruption import ObjectInterruption
from SimPy.Simulation import waituntil, now, hold, request, release, waitevent # from SimPy.Simulation import waituntil, now, hold, request, release, waitevent
# =========================================================================== # ===========================================================================
# Class that handles the Operator Behavior # Class that handles the Operator Behavior
...@@ -48,8 +49,8 @@ class Broker(ObjectInterruption): ...@@ -48,8 +49,8 @@ class Broker(ObjectInterruption):
self.timeLastOperationEnded = 0 self.timeLastOperationEnded = 0
self.timeWaitForOperatorStarted=0 self.timeWaitForOperatorStarted=0
# Broker events # Broker events
self.isCalled=SimEvent('brokerIsCalled') self.isCalled=self.env.event()#SimEvent('brokerIsCalled')
self.resourceAvailable=SimEvent('resourceAvailable') self.resourceAvailable=self.env.event()#SimEvent('resourceAvailable')
self.waitForOperator=False self.waitForOperator=False
#=========================================================================== #===========================================================================
...@@ -69,15 +70,16 @@ class Broker(ObjectInterruption): ...@@ -69,15 +70,16 @@ class Broker(ObjectInterruption):
def run(self): def run(self):
while 1: while 1:
# TODO: add new broker event - brokerIsCalled # TODO: add new broker event - brokerIsCalled
yield waitevent, self, self.isCalled yield self.isCalled
assert self.isCalled.signalparam==now(), 'the broker should be granted control instantly' assert self.isCalled.value==self.env.now, 'the broker should be granted control instantly'
self.isCalled=self.env.event()
self.victim.printTrace(self.victim.id, received='(broker)') self.victim.printTrace(self.victim.id, received='(broker)')
# ======= 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=self.env.now#()
#=============================================================== #===============================================================
# if the victim already holds an entity that means that the machine's operation type # 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 # is no Load or setup, in that case the router is already invoked and the machine is already assigned an operator
...@@ -89,51 +91,66 @@ class Broker(ObjectInterruption): ...@@ -89,51 +91,66 @@ class Broker(ObjectInterruption):
if not G.Router.invoked: if not G.Router.invoked:
self.victim.printTrace(self.victim.id, signal='router (broker)') self.victim.printTrace(self.victim.id, signal='router (broker)')
G.Router.invoked=True G.Router.invoked=True
G.Router.isCalled.signal(now()) G.Router.isCalled.succeed(self.env.now)
self.waitForOperator=True self.waitForOperator=True
self.victim.printTrace(self.victim.id, waitEvent='(resourceIsAvailable broker)') self.victim.printTrace(self.victim.id, waitEvent='(resourceIsAvailable broker)')
yield waitevent, self, self.resourceAvailable yield self.resourceAvailable
self.resourceAvailable=self.env.event()
# remove the currentEntity from the pendingEntities # remove the currentEntity from the pendingEntities
if self.victim.currentEntity in G.pendingEntities: if self.victim.currentEntity in G.pendingEntities:
G.pendingEntities.remove(self.victim.currentEntity) G.pendingEntities.remove(self.victim.currentEntity)
self.waitForOperator=False self.waitForOperator=False
self.victim.printTrace(self.victim.id, resourceAvailable='(broker)') self.victim.printTrace(self.victim.id, resourceAvailable='(broker)')
#=============================================================== #===============================================================
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()
yield request, self, self.victim.operatorPool.getResource(self.victim.currentOperator)
self.victim.printTrace(self.victim.currentOperator.objName, startWork=self.victim.id)
# 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
yield release,self,self.victim.operatorPool.getResource(self.victim.currentOperator)
# signal the other brokers waiting for the same operators that they are now free
# also signal the stations that were not requested to receive because the operator was occupied
# TODO: signalling the router must be done more elegantly, router must be set as global variable
# if the router is already invoked then do not signal it again
if not self.victim.router.invoked:
self.victim.printTrace(self.victim.id, signal='router (broker)')
self.victim.router.invoked=True
self.victim.router.isCalled.signal(now())
# TODO: signalling the router will give the chance to it to take the control, but when will it eventually receive it.
# after signalling the broker will signal it's victim that it has finished it's processes
# TODO: this wont work for the moment. The actions that follow must be performed by all operated brokers.
self.victim.printTrace(self.victim.currentOperator.objName, finishWork=self.victim.id) with self.victim.operatorPool.getResource(self.victim.currentOperator).request() as request:
# the victim current operator must be cleared after the operator is released yield request
self.timeLastOperationEnded = now() self.victim.printTrace(self.victim.currentOperator.objName, startWork=self.victim.id)
self.victim.currentOperator = None # clear the timeWaitForOperatorStarted variable
else: self.timeWaitForOperatorStarted = 0
pass # update the time that the operation started
# TODO: the victim must have a new event brokerIsSet self.timeOperationStarted = self.env.now#()
self.victim.brokerIsSet.signal(now()) self.victim.outputTrace(self.victim.currentOperator.objName, "started work in "+ self.victim.objName)
self.victim.currentOperator.timeLastOperationStarted=self.env.now#()
\ No newline at end of file # signal the machine that an operator is reserved
self.victim.brokerIsSet.succeed(self.env.now)
# wait till the processing is over
yield self.isCalled
assert self.isCalled.value==self.env.now, 'the broker should be granted control instantly'
self.isCalled=self.env.event()
# The operator is released
if not self.victim.isOperated():
self.victim.currentOperator.totalWorkingTime+=self.env.now-self.victim.currentOperator.timeLastOperationStarted
# signal the other brokers waiting for the same operators that they are now free
# also signal the stations that were not requested to receive because the operator was occupied
# TODO: signalling the router must be done more elegantly, router must be set as global variable
# if the router is already invoked then do not signal it again
if not self.victim.router.invoked:
self.victim.printTrace(self.victim.id, signal='router (broker)')
self.victim.router.invoked=True
# self.victim.router.isCalled.signal(now())
self.victim.router.isCalled.succeed(self.env.now)
# TODO: signalling the router will give the chance to it to take the control, but when will it eventually receive it.
# after signalling the broker will signal it's victim that it has finished it's processes
# TODO: this wont work for the moment. The actions that follow must be performed by all operated brokers.
self.victim.printTrace(self.victim.currentOperator.objName, finishWork=self.victim.id)
# the victim current operator must be cleared after the operator is released
self.timeLastOperationEnded = self.env.now
self.victim.currentOperator = None
else:
pass
# return the control to the victim
self.victim.brokerIsSet.succeed(self.env.now)
...@@ -25,9 +25,11 @@ Created on 19 Feb 2013 ...@@ -25,9 +25,11 @@ Created on 19 Feb 2013
''' '''
Models an Interruption that schedules the operation of the machines by different managers Models an Interruption that schedules the operation of the machines by different managers
''' '''
from SimPy.Globals import sim # from SimPy.Globals import sim
from SimPy.Simulation import Simulation # from SimPy.Simulation import Simulation
from SimPy.Simulation import Process, Resource, SimEvent # from SimPy.Simulation import Process, Resource, SimEvent
import simpy
from ObjectInterruption import ObjectInterruption from ObjectInterruption import ObjectInterruption
from SimPy.Simulation import waituntil, now, hold, request, release, waitevent from SimPy.Simulation import waituntil, now, hold, request, release, waitevent
...@@ -48,7 +50,7 @@ class Router(ObjectInterruption): ...@@ -48,7 +50,7 @@ class Router(ObjectInterruption):
ObjectInterruption.__init__(self) ObjectInterruption.__init__(self)
self.type = "Router" self.type = "Router"
# signal used to initiate the generator of the Router # signal used to initiate the generator of the Router
self.isCalled=SimEvent('RouterIsCalled') self.isCalled=self.env.event()
self.isInitialized=False self.isInitialized=False
self.candidateOperators=[] self.candidateOperators=[]
self.multipleCriterionList=[] self.multipleCriterionList=[]
...@@ -118,14 +120,15 @@ class Router(ObjectInterruption): ...@@ -118,14 +120,15 @@ class Router(ObjectInterruption):
break break
while 1: while 1:
# wait until the router is called # wait until the router is called
yield waitevent, self, self.isCalled yield self.isCalled
self.isCalled=self.env.event()
self.printTrace('','=-'*15) self.printTrace('','=-'*15)
self.printTrace('','router received event') self.printTrace('','router received event')
# wait till there are no more events, the machines must be blocked # wait till there are no more events, the machines must be blocked
while 1: while 1:
if now() in Simulation.allEventTimes(sim): if self.env.now==self.env.peek():
self.printTrace('', 'there are MORE events for now') self.printTrace('', 'there are MORE events for now')
yield hold, self, 0 yield self.env.timeout(0)
else: else:
self.printTrace('','there are NO more events for now') self.printTrace('','there are NO more events for now')
break break
...@@ -277,28 +280,28 @@ class Router(ObjectInterruption): ...@@ -277,28 +280,28 @@ class Router(ObjectInterruption):
operator.getResourceQueue()[0].victim.shouldPreempt=True operator.getResourceQueue()[0].victim.shouldPreempt=True
self.printTrace('router', 'preempting '+operator.getResourceQueue()[0].victim.id+'.. '*6) self.printTrace('router', 'preempting '+operator.getResourceQueue()[0].victim.id+'.. '*6)
operator.getResourceQueue()[0].victim.preempt() operator.getResourceQueue()[0].victim.preempt()
operator.getResourceQueue()[0].victim.timeLastEntityEnded=now() #required to count blockage correctly in the preemptied station operator.getResourceQueue()[0].victim.timeLastEntityEnded=self.env.now #required to count blockage correctly in the preemptied station
station.shouldPreempt=True station.shouldPreempt=True
self.printTrace('router', 'preempting receiver '+station.id+'.. '*6) self.printTrace('router', 'preempting receiver '+station.id+'.. '*6)
station.preempt() station.preempt()
station.timeLastEntityEnded=now() #required to count blockage correctly in the preemptied station station.timeLastEntityEnded=self.env.now #required to count blockage correctly in the preemptied station
elif station.broker.waitForOperator: elif station.broker.waitForOperator:
# signal this station's broker that the resource is available # signal this station's broker that the resource is available
self.printTrace('router', 'signalling broker of'+' '*50+operator.isAssignedTo().id) self.printTrace('router', 'signalling broker of'+' '*50+operator.isAssignedTo().id)
station.broker.resourceAvailable.signal(now()) station.broker.resourceAvailable.succeed(self.env.now)
else: else:
# signal the queue proceeding the station # signal the queue proceeding the station
if station.canAccept()\ if station.canAccept()\
and any(type=='Load' for type in station.multOperationTypeList): and any(type=='Load' for type in station.multOperationTypeList):
self.printTrace('router', 'signalling'+' '*50+operator.isAssignedTo().id) self.printTrace('router', 'signalling'+' '*50+operator.isAssignedTo().id)
station.loadOperatorAvailable.signal(now()) station.loadOperatorAvailable.succeed(self.env.now)
# in case the router deals with managed entities # in case the router deals with managed entities
#------------------------------------------------------------------------------ #------------------------------------------------------------------------------
else: else:
if station in self.pendingMachines and station in self.toBeSignalled: if station in self.pendingMachines and station in self.toBeSignalled:
# signal this station's broker that the resource is available # signal this station's broker that the resource is available
self.printTrace('router','signalling broker of'+' '*50+operator.isAssignedTo().id) self.printTrace('router','signalling broker of'+' '*50+operator.isAssignedTo().id)
operator.isAssignedTo().broker.resourceAvailable.signal(now()) operator.isAssignedTo().broker.resourceAvailable.succeed(self.env.now)
elif (not station in self.pendingMachines) or (not station in self.toBeSignalled): elif (not station in self.pendingMachines) or (not station in self.toBeSignalled):
# signal the queue proceeding the station # signal the queue proceeding the station
assert operator.candidateEntity.currentStation in self.toBeSignalled, 'the candidateEntity currentStation is not picked by the Router' assert operator.candidateEntity.currentStation in self.toBeSignalled, 'the candidateEntity currentStation is not picked by the Router'
...@@ -306,7 +309,7 @@ class Router(ObjectInterruption): ...@@ -306,7 +309,7 @@ class Router(ObjectInterruption):
if operator.candidateEntity.candidateReceiver.canAccept()\ if operator.candidateEntity.candidateReceiver.canAccept()\
and any(type=='Load' for type in operator.candidateEntity.candidateReceiver.multOperationTypeList): and any(type=='Load' for type in operator.candidateEntity.candidateReceiver.multOperationTypeList):
self.printTrace('router','signalling queue'+' '*50+operator.candidateEntity.currentStation.id) self.printTrace('router','signalling queue'+' '*50+operator.candidateEntity.currentStation.id)
operator.candidateEntity.currentStation.loadOperatorAvailable.signal(now()) operator.candidateEntity.currentStation.loadOperatorAvailable.succeed(self.env.now)
#=========================================================================== #===========================================================================
# clear the pending lists of the router # clear the pending lists of the router
......
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