failure, objectInterruption, and queue updated

parent a6618f51
...@@ -483,7 +483,7 @@ class CoreObject(object): ...@@ -483,7 +483,7 @@ class CoreObject(object):
# loop through the possible givers to see which have to dispose and which is the one blocked for longer # loop through the possible givers to see which have to dispose and which is the one blocked for longer
for object in candidates: for object in candidates:
if(object.downTimeInTryingToReleaseCurrentEntity>0):# and the predecessor has been down while trying to give away the Entity if(object.downTimeInTryingToReleaseCurrentEntity>0):# and the predecessor has been down while trying to give away the Entity
timeWaiting=self.env.now-object.timeLastFailureEnded # the timeWaiting dummy variable counts the time end of the last failure of the giver object timeWaiting=G.env.now-object.timeLastFailureEnded # the timeWaiting dummy variable counts the time end of the last failure of the giver object
else: else:
timeWaiting=G.env.now-object.timeLastEntityEnded # in any other case, it holds the time since the end of the Entity processing timeWaiting=G.env.now-object.timeLastEntityEnded # in any other case, it holds the time since the end of the Entity processing
#if more than one predecessor have to dispose take the part from the one that is blocked longer #if more than one predecessor have to dispose take the part from the one that is blocked longer
......
...@@ -26,7 +26,8 @@ Created on 9 Nov 2012 ...@@ -26,7 +26,8 @@ Created on 9 Nov 2012
models the failures that servers can have models the failures that servers can have
''' '''
from SimPy.Simulation import now, Process, hold, request, release # from SimPy.Simulation import now, Process, hold, request, release
import simpy
import math import math
from RandomNumberGenerator import RandomNumberGenerator from RandomNumberGenerator import RandomNumberGenerator
from ObjectInterruption import ObjectInterruption from ObjectInterruption import ObjectInterruption
...@@ -86,28 +87,28 @@ class Failure(ObjectInterruption): ...@@ -86,28 +87,28 @@ class Failure(ObjectInterruption):
# ======================================================================= # =======================================================================
def run(self): def run(self):
while 1: while 1:
yield hold,self,self.rngTTF.generateNumber() # wait until a failure happens yield self.env.timeout(self.rngTTF.generateNumber()) # wait until a failure happens
self.interruptVictim() # interrupt the victim self.interruptVictim() # interrupt the victim
self.victim.Up=False self.victim.Up=False
self.victim.timeLastFailure=now() self.victim.timeLastFailure=self.env.now
self.outputTrace("is down") self.outputTrace("is down")
# update the failure time # update the failure time
failTime=now() failTime=self.env.now
if(self.repairman and self.repairman!="None"): #if the failure needs a resource to be fixed, the machine waits until the if(self.repairman and self.repairman!="None"): #if the failure needs a resource to be fixed, the machine waits until the
#resource is available #resource is available
yield request,self,self.repairman.getResource() yield self.repairman.getResource().request()
# update the time that the repair started # update the time that the repair started
timeOperationStarted=now() timeOperationStarted=self.env.now
self.repairman.timeLastOperationStarted=now() self.repairman.timeLastOperationStarted=self.env.now
yield hold,self,self.rngTTR.generateNumber() # wait until the repairing process is over yield self.env.timeout(self.rngTTR.generateNumber()) # wait until the repairing process is over
self.victim.totalFailureTime+=now()-failTime self.victim.totalFailureTime+=self.env.now-failTime
self.reactivateVictim() # since repairing is over, the Machine is reactivated self.reactivateVictim() # since repairing is over, the Machine is reactivated
self.victim.Up=True self.victim.Up=True
self.outputTrace("is up") self.outputTrace("is up")
if(self.repairman and self.repairman!="None"): #if a resource was used, it is now released if(self.repairman and self.repairman!="None"): #if a resource was used, it is now released
yield release,self,self.repairman.getResource() self.repairman.getResource().release()
self.repairman.totalWorkingTime+=now()-timeOperationStarted self.repairman.totalWorkingTime+=self.env.now-timeOperationStarted
# #=========================================================================== # #===========================================================================
# # interrupts the victim # # interrupts the victim
......
...@@ -26,15 +26,18 @@ Created on 18 Aug 2013 ...@@ -26,15 +26,18 @@ Created on 18 Aug 2013
Class that acts as an abstract. It should have no instances. All object interruptions (eg failures, breaks) should inherit from it Class that acts as an abstract. It should have no instances. All object interruptions (eg failures, breaks) should inherit from it
''' '''
from SimPy.Simulation import Process, Resource, reactivate, now # from SimPy.Simulation import Process, Resource, reactivate, now
import simpy
#=============================================================================== #===============================================================================
# The ObjectInterruption process # The ObjectInterruption process
#=============================================================================== #===============================================================================
class ObjectInterruption(Process): class ObjectInterruption(object):
def __init__(self, victim=None): def __init__(self, victim=None):
Process.__init__(self) from Globals import G
self.env=G.env
# Process.__init__(self)
self.victim=victim self.victim=victim
# variable used to hand in control to the objectInterruption # variable used to hand in control to the objectInterruption
self.call=False self.call=False
...@@ -57,7 +60,7 @@ class ObjectInterruption(Process): ...@@ -57,7 +60,7 @@ class ObjectInterruption(Process):
# signalling can be done via Machine request/releaseOperator # signalling can be done via Machine request/releaseOperator
# ======================================================================= # =======================================================================
def invoke(self): def invoke(self):
self.isCalled.signal(now()) self.isCalled.succeed(self.env.now)
#=========================================================================== #===========================================================================
# outputs data to "output.xls" # outputs data to "output.xls"
...@@ -87,18 +90,21 @@ class ObjectInterruption(Process): ...@@ -87,18 +90,21 @@ class ObjectInterruption(Process):
# interrupts the victim # interrupts the victim
#=========================================================================== #===========================================================================
def interruptVictim(self): def interruptVictim(self):
# if the victim is not in position to dispose an entity, then interrupt the processing # # if the victim is not in position to dispose an entity, then interrupt the processing
if not self.victim.waitToDispose and self.victim.getActiveObjectQueue(): # if not self.victim.waitToDispose and self.victim.getActiveObjectQueue():
self.interrupt(self.victim) # self.interrupt(self.victim)
# otherwise it waits for an interruption event # otherwise it waits for an interruption event
else: # else:
self.victim.interruptionStart.signal(now()) # self.victim.interruptionStart.signal(now())
self.victim.interruptionStart.succeed(self.env.now)
#=========================================================================== #===========================================================================
# reactivate the victim # reactivate the victim
#=========================================================================== #===========================================================================
def reactivateVictim(self): def reactivateVictim(self):
self.victim.interruptionEnd.signal(now()) self.victim.interruptionEnd.succeed(self.env.now)
#reset the interruptionStart event of the victim
self.victim.interruptionStart=self.env.event()
#=========================================================================== #===========================================================================
# outputs message to the trace.xls. Format is (Simulation Time | Victim Name | message) # outputs message to the trace.xls. Format is (Simulation Time | Victim Name | message)
...@@ -107,7 +113,7 @@ class ObjectInterruption(Process): ...@@ -107,7 +113,7 @@ class ObjectInterruption(Process):
from Globals import G from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to if(G.trace=="Yes"): #output only if the user has selected to
#handle the 3 columns #handle the 3 columns
G.traceSheet.write(G.traceIndex,0,str(now())) G.traceSheet.write(G.traceIndex,0,str(self.env.now))
G.traceSheet.write(G.traceIndex,1, self.victim.objName) G.traceSheet.write(G.traceIndex,1, self.victim.objName)
G.traceSheet.write(G.traceIndex,2,message) G.traceSheet.write(G.traceIndex,2,message)
G.traceIndex+=1 #increment the row G.traceIndex+=1 #increment the row
...@@ -124,4 +130,4 @@ class ObjectInterruption(Process): ...@@ -124,4 +130,4 @@ class ObjectInterruption(Process):
def printTrace(self, entityName, message): def printTrace(self, entityName, message):
from Globals import G from Globals import G
if(G.console=="Yes"): #output only if the user has selected to if(G.console=="Yes"): #output only if the user has selected to
print now(), entityName, message print self.env.now, entityName, message
\ No newline at end of file \ No newline at end of file
...@@ -26,8 +26,9 @@ Models a FIFO queue where entities can wait in order to get into a server ...@@ -26,8 +26,9 @@ Models a FIFO queue where entities can wait in order to get into a server
''' '''
from SimPy.Simulation import Process, Resource, SimEvent # from SimPy.Simulation import Process, Resource, SimEvent
from SimPy.Simulation import waituntil, now, infinity, waitevent # from SimPy.Simulation import waituntil, now, infinity, waitevent
import simpy
from CoreObject import CoreObject from CoreObject import CoreObject
# =========================================================================== # ===========================================================================
# the Queue object # the Queue object
...@@ -69,7 +70,7 @@ class Queue(CoreObject): ...@@ -69,7 +70,7 @@ class Queue(CoreObject):
# Will be populated by an event generator # Will be populated by an event generator
self.wip_stat_list = [] self.wip_stat_list = []
# event used by router # event used by router
self.loadOperatorAvailable=SimEvent('loadOperatorAvailable') self.loadOperatorAvailable=self.env.event()
@staticmethod @staticmethod
def getSupportedSchedulingRules(): def getSupportedSchedulingRules():
...@@ -83,40 +84,40 @@ class Queue(CoreObject): ...@@ -83,40 +84,40 @@ class Queue(CoreObject):
# using the Process __init__ and not the CoreObject __init__ # using the Process __init__ and not the CoreObject __init__
CoreObject.initialize(self) CoreObject.initialize(self)
# initialise the internal Queue (type Resource) of the Queue object # initialise the internal Queue (type Resource) of the Queue object
self.Res=Resource(self.capacity) self.Res=simpy.Resource(self.env, self.capacity)
# event used by router # event used by router
self.loadOperatorAvailable=SimEvent('loadOperatorAvailable') self.loadOperatorAvailable=self.env.event()
#=========================================================================== #===========================================================================
# run method of the queue # run method of the queue
#=========================================================================== #===========================================================================
def run(self): def run(self):
activeObjectQueue=self.Res.activeQ activeObjectQueue=self.Res.users
# check if there is WIP and signal receiver # check if there is WIP and signal receiver
self.initialSignalReceiver() self.initialSignalReceiver()
while 1: while 1:
# self.printTrace(self.id, waitEvent='') # self.printTrace(self.id, waitEvent='')
# wait until the Queue can accept an entity and one predecessor requests it # wait until the Queue can accept an entity and one predecessor requests it
yield waitevent, self, [self.isRequested,self.canDispose, self.loadOperatorAvailable] receivedEvent=yield self.isRequested | self.canDispose | self.loadOperatorAvailable
# self.printTrace(self.id, received='') # self.printTrace(self.id, received='')
# if the event that activated the thread is isRequested then getEntity # if the event that activated the thread is isRequested then getEntity
if self.isRequested.signalparam: if self.isRequested in receivedEvent:
# self.printTrace(self.id, isRequested=self.isRequested.signalparam.id) # self.printTrace(self.id, isRequested=self.isRequested.signalparam.id)
# reset the isRequested signal parameter # reset the isRequested signal parameter
self.isRequested.signalparam=None self.isRequested=self.env.event()
self.getEntity() self.getEntity()
#if entity just got to the dummyQ set its startTime as the current time #if entity just got to the dummyQ set its startTime as the current time
if self.isDummy: if self.isDummy:
activeObjectQueue[0].startTime=now() activeObjectQueue[0].startTime=self.env.now
# if the queue received an loadOperatorIsAvailable (from Router) with signalparam time # if the queue received an loadOperatorIsAvailable (from Router) with signalparam time
if self.loadOperatorAvailable.signalparam: if self.loadOperatorAvailable:
# self.printTrace(self.id, loadOperatorAvailable=str(self.loadOperatorAvailable.signalparam)) # self.printTrace(self.id, loadOperatorAvailable=str(self.loadOperatorAvailable.signalparam))
self.loadOperatorAvailable.signalparam=None self.loadOperatorAvailable=self.env.event()
# if the queue received an canDispose with signalparam time, this means that the signals was sent from a MouldAssemblyBuffer # if the queue received an canDispose with signalparam time, this means that the signals was sent from a MouldAssemblyBuffer
if self.canDispose.signalparam: if self.canDispose in receivedEvent:
# self.printTrace(self.id, canDispose='') # self.printTrace(self.id, canDispose='')
self.canDispose.signalparam=None self.canDispose=self.env.event()
# if the event that activated the thread is canDispose then signalReceiver # if the event that activated the thread is canDispose then signalReceiver
if self.haveToDispose(): if self.haveToDispose():
# self.printTrace(self.id, attemptSignalReceiver='(generator)') # self.printTrace(self.id, attemptSignalReceiver='(generator)')
...@@ -132,7 +133,7 @@ class Queue(CoreObject): ...@@ -132,7 +133,7 @@ class Queue(CoreObject):
# only to the predecessor that will give the entity. # only to the predecessor that will give the entity.
# ======================================================================= # =======================================================================
def canAccept(self, callerObject=None): def canAccept(self, callerObject=None):
activeObjectQueue=self.Res.activeQ activeObjectQueue=self.Res.users
#if we have only one predecessor just check if there is a place available #if we have only one predecessor just check if there is a place available
# 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
...@@ -148,7 +149,7 @@ class Queue(CoreObject): ...@@ -148,7 +149,7 @@ class Queue(CoreObject):
# this is kind of slow I think got to check # this is kind of slow I think got to check
# ======================================================================= # =======================================================================
def haveToDispose(self, callerObject=None): def haveToDispose(self, callerObject=None):
activeObjectQueue=self.Res.activeQ activeObjectQueue=self.Res.users
#if we have only one possible receiver just check if the Queue holds one or more entities #if we have only one possible receiver just check if the Queue holds one or more entities
if(callerObject==None): if(callerObject==None):
return len(activeObjectQueue)>0 return len(activeObjectQueue)>0
...@@ -175,7 +176,7 @@ class Queue(CoreObject): ...@@ -175,7 +176,7 @@ class Queue(CoreObject):
# also updates the predecessorIndex to the one that is to be taken # also updates the predecessorIndex to the one that is to be taken
# ======================================================================= # =======================================================================
def canAcceptAndIsRequested(self,callerObject=None): def canAcceptAndIsRequested(self,callerObject=None):
activeObjectQueue=self.Res.activeQ activeObjectQueue=self.Res.users
giverObject=callerObject giverObject=callerObject
assert giverObject, 'there must be a caller for canAcceptAndIsRequested' assert giverObject, 'there must be a caller for canAcceptAndIsRequested'
return len(activeObjectQueue)<self.capacity and giverObject.haveToDispose(self) return len(activeObjectQueue)<self.capacity and giverObject.haveToDispose(self)
...@@ -219,7 +220,7 @@ class Queue(CoreObject): ...@@ -219,7 +220,7 @@ class Queue(CoreObject):
# sorts the Entities of the Queue according to the scheduling rule # sorts the Entities of the Queue according to the scheduling rule
# ======================================================================= # =======================================================================
def activeQSorter(self, criterion=None): def activeQSorter(self, criterion=None):
activeObjectQ=self.Res.activeQ activeObjectQ=self.Res.users
if criterion==None: if criterion==None:
criterion=self.schedulingRule criterion=self.schedulingRule
#if the schedulingRule is first in first out #if the schedulingRule is first in first out
...@@ -284,7 +285,7 @@ class Queue(CoreObject): ...@@ -284,7 +285,7 @@ class Queue(CoreObject):
for obj in G.ObjList: for obj in G.ObjList:
if obj.id in nextObjIds: if obj.id in nextObjIds:
nextObject=obj nextObject=obj
entity.nextQueueLength=len(nextObject.Res.activeQ) entity.nextQueueLength=len(nextObject.Res.users)
activeObjectQ.sort(key=lambda x: x.nextQueueLength) activeObjectQ.sort(key=lambda x: x.nextQueueLength)
else: else:
assert False, "Unknown scheduling criterion %r" % (criterion, ) assert False, "Unknown scheduling criterion %r" % (criterion, )
......
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