Router and Broker updated

parent 78428476
......@@ -26,9 +26,10 @@ Created on 27 Nov 2013
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 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
......@@ -48,8 +49,8 @@ class Broker(ObjectInterruption):
self.timeLastOperationEnded = 0
self.timeWaitForOperatorStarted=0
# Broker events
self.isCalled=SimEvent('brokerIsCalled')
self.resourceAvailable=SimEvent('resourceAvailable')
self.isCalled=self.env.event()#SimEvent('brokerIsCalled')
self.resourceAvailable=self.env.event()#SimEvent('resourceAvailable')
self.waitForOperator=False
#===========================================================================
......@@ -69,15 +70,16 @@ class Broker(ObjectInterruption):
def run(self):
while 1:
# TODO: add new broker event - brokerIsCalled
yield waitevent, self, self.isCalled
assert self.isCalled.signalparam==now(), 'the broker should be granted control instantly'
yield self.isCalled
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)')
# ======= 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()
self.timeWaitForOperatorStarted=self.env.now#()
#===============================================================
# 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
......@@ -89,51 +91,66 @@ class Broker(ObjectInterruption):
if not G.Router.invoked:
self.victim.printTrace(self.victim.id, signal='router (broker)')
G.Router.invoked=True
G.Router.isCalled.signal(now())
G.Router.isCalled.succeed(self.env.now)
self.waitForOperator=True
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
if self.victim.currentEntity in G.pendingEntities:
G.pendingEntities.remove(self.victim.currentEntity)
self.waitForOperator=False
self.victim.printTrace(self.victim.id, resourceAvailable='(broker)')
#===============================================================
assert self.victim.operatorPool.checkIfResourceIsAvailable(), 'there is no available operator to request'
# set the available resource as the currentOperator
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)
# the victim current operator must be cleared after the operator is released
self.timeLastOperationEnded = now()
self.victim.currentOperator = None
else:
pass
# TODO: the victim must have a new event brokerIsSet
self.victim.brokerIsSet.signal(now())
\ No newline at end of file
with self.victim.operatorPool.getResource(self.victim.currentOperator).request() as request:
yield request
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 = self.env.now#()
self.victim.outputTrace(self.victim.currentOperator.objName, "started work in "+ self.victim.objName)
self.victim.currentOperator.timeLastOperationStarted=self.env.now#()
# 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
'''
Models an Interruption that schedules the operation of the machines by different managers
'''
from SimPy.Globals import sim
from SimPy.Simulation import Simulation
from SimPy.Simulation import Process, Resource, SimEvent
# from SimPy.Globals import sim
# from SimPy.Simulation import Simulation
# from SimPy.Simulation import Process, Resource, SimEvent
import simpy
from ObjectInterruption import ObjectInterruption
from SimPy.Simulation import waituntil, now, hold, request, release, waitevent
......@@ -48,7 +50,7 @@ class Router(ObjectInterruption):
ObjectInterruption.__init__(self)
self.type = "Router"
# signal used to initiate the generator of the Router
self.isCalled=SimEvent('RouterIsCalled')
self.isCalled=self.env.event()
self.isInitialized=False
self.candidateOperators=[]
self.multipleCriterionList=[]
......@@ -118,14 +120,15 @@ class Router(ObjectInterruption):
break
while 1:
# wait until the router is called
yield waitevent, self, self.isCalled
yield self.isCalled
self.isCalled=self.env.event()
self.printTrace('','=-'*15)
self.printTrace('','router received event')
# wait till there are no more events, the machines must be blocked
while 1:
if now() in Simulation.allEventTimes(sim):
if self.env.now==self.env.peek():
self.printTrace('', 'there are MORE events for now')
yield hold, self, 0
yield self.env.timeout(0)
else:
self.printTrace('','there are NO more events for now')
break
......@@ -277,28 +280,28 @@ class Router(ObjectInterruption):
operator.getResourceQueue()[0].victim.shouldPreempt=True
self.printTrace('router', 'preempting '+operator.getResourceQueue()[0].victim.id+'.. '*6)
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
self.printTrace('router', 'preempting receiver '+station.id+'.. '*6)
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:
# signal this station's broker that the resource is available
self.printTrace('router', 'signalling broker of'+' '*50+operator.isAssignedTo().id)
station.broker.resourceAvailable.signal(now())
station.broker.resourceAvailable.succeed(self.env.now)
else:
# signal the queue proceeding the station
if station.canAccept()\
and any(type=='Load' for type in station.multOperationTypeList):
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
#------------------------------------------------------------------------------
else:
if station in self.pendingMachines and station in self.toBeSignalled:
# signal this station's broker that the resource is available
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):
# signal the queue proceeding the station
assert operator.candidateEntity.currentStation in self.toBeSignalled, 'the candidateEntity currentStation is not picked by the Router'
......@@ -306,7 +309,7 @@ class Router(ObjectInterruption):
if operator.candidateEntity.candidateReceiver.canAccept()\
and any(type=='Load' for type in operator.candidateEntity.candidateReceiver.multOperationTypeList):
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
......
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