failure, objectInterruption, and queue updated

parent a6618f51
......@@ -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
for object in candidates:
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:
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
......
......@@ -26,7 +26,8 @@ Created on 9 Nov 2012
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
from RandomNumberGenerator import RandomNumberGenerator
from ObjectInterruption import ObjectInterruption
......@@ -86,28 +87,28 @@ class Failure(ObjectInterruption):
# =======================================================================
def run(self):
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.victim.Up=False
self.victim.timeLastFailure=now()
self.victim.timeLastFailure=self.env.now
self.outputTrace("is down")
# 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
#resource is available
yield request,self,self.repairman.getResource()
yield self.repairman.getResource().request()
# update the time that the repair started
timeOperationStarted=now()
self.repairman.timeLastOperationStarted=now()
timeOperationStarted=self.env.now
self.repairman.timeLastOperationStarted=self.env.now
yield hold,self,self.rngTTR.generateNumber() # wait until the repairing process is over
self.victim.totalFailureTime+=now()-failTime
yield self.env.timeout(self.rngTTR.generateNumber()) # wait until the repairing process is over
self.victim.totalFailureTime+=self.env.now-failTime
self.reactivateVictim() # since repairing is over, the Machine is reactivated
self.victim.Up=True
self.outputTrace("is up")
if(self.repairman and self.repairman!="None"): #if a resource was used, it is now released
yield release,self,self.repairman.getResource()
self.repairman.totalWorkingTime+=now()-timeOperationStarted
self.repairman.getResource().release()
self.repairman.totalWorkingTime+=self.env.now-timeOperationStarted
# #===========================================================================
# # interrupts the victim
......
......@@ -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
'''
from SimPy.Simulation import Process, Resource, reactivate, now
# from SimPy.Simulation import Process, Resource, reactivate, now
import simpy
#===============================================================================
# The ObjectInterruption process
#===============================================================================
class ObjectInterruption(Process):
class ObjectInterruption(object):
def __init__(self, victim=None):
Process.__init__(self)
from Globals import G
self.env=G.env
# Process.__init__(self)
self.victim=victim
# variable used to hand in control to the objectInterruption
self.call=False
......@@ -57,7 +60,7 @@ class ObjectInterruption(Process):
# signalling can be done via Machine request/releaseOperator
# =======================================================================
def invoke(self):
self.isCalled.signal(now())
self.isCalled.succeed(self.env.now)
#===========================================================================
# outputs data to "output.xls"
......@@ -87,18 +90,21 @@ class ObjectInterruption(Process):
# interrupts the victim
#===========================================================================
def interruptVictim(self):
# if the victim is not in position to dispose an entity, then interrupt the processing
if not self.victim.waitToDispose and self.victim.getActiveObjectQueue():
self.interrupt(self.victim)
# # if the victim is not in position to dispose an entity, then interrupt the processing
# if not self.victim.waitToDispose and self.victim.getActiveObjectQueue():
# self.interrupt(self.victim)
# otherwise it waits for an interruption event
else:
self.victim.interruptionStart.signal(now())
# else:
# self.victim.interruptionStart.signal(now())
self.victim.interruptionStart.succeed(self.env.now)
#===========================================================================
# reactivate the victim
#===========================================================================
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)
......@@ -107,7 +113,7 @@ class ObjectInterruption(Process):
from Globals import G
if(G.trace=="Yes"): #output only if the user has selected to
#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,2,message)
G.traceIndex+=1 #increment the row
......@@ -124,4 +130,4 @@ class ObjectInterruption(Process):
def printTrace(self, entityName, message):
from Globals import G
if(G.console=="Yes"): #output only if the user has selected to
print now(), entityName, message
\ No newline at end of file
print self.env.now, entityName, message
\ 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
'''
from SimPy.Simulation import Process, Resource, SimEvent
from SimPy.Simulation import waituntil, now, infinity, waitevent
# from SimPy.Simulation import Process, Resource, SimEvent
# from SimPy.Simulation import waituntil, now, infinity, waitevent
import simpy
from CoreObject import CoreObject
# ===========================================================================
# the Queue object
......@@ -69,7 +70,7 @@ class Queue(CoreObject):
# Will be populated by an event generator
self.wip_stat_list = []
# event used by router
self.loadOperatorAvailable=SimEvent('loadOperatorAvailable')
self.loadOperatorAvailable=self.env.event()
@staticmethod
def getSupportedSchedulingRules():
......@@ -83,40 +84,40 @@ class Queue(CoreObject):
# using the Process __init__ and not the CoreObject __init__
CoreObject.initialize(self)
# 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
self.loadOperatorAvailable=SimEvent('loadOperatorAvailable')
self.loadOperatorAvailable=self.env.event()
#===========================================================================
# run method of the queue
#===========================================================================
def run(self):
activeObjectQueue=self.Res.activeQ
activeObjectQueue=self.Res.users
# check if there is WIP and signal receiver
self.initialSignalReceiver()
while 1:
# self.printTrace(self.id, waitEvent='')
# 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='')
# 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)
# reset the isRequested signal parameter
self.isRequested.signalparam=None
self.isRequested=self.env.event()
self.getEntity()
#if entity just got to the dummyQ set its startTime as the current time
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 self.loadOperatorAvailable.signalparam:
if self.loadOperatorAvailable:
# 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 self.canDispose.signalparam:
if self.canDispose in receivedEvent:
# 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 self.haveToDispose():
# self.printTrace(self.id, attemptSignalReceiver='(generator)')
......@@ -132,7 +133,7 @@ class Queue(CoreObject):
# only to the predecessor that will give the entity.
# =======================================================================
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
# this is done to achieve better (cpu) processing time
# then we can also use it as a filter for a yield method
......@@ -148,7 +149,7 @@ class Queue(CoreObject):
# this is kind of slow I think got to check
# =======================================================================
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(callerObject==None):
return len(activeObjectQueue)>0
......@@ -175,7 +176,7 @@ class Queue(CoreObject):
# also updates the predecessorIndex to the one that is to be taken
# =======================================================================
def canAcceptAndIsRequested(self,callerObject=None):
activeObjectQueue=self.Res.activeQ
activeObjectQueue=self.Res.users
giverObject=callerObject
assert giverObject, 'there must be a caller for canAcceptAndIsRequested'
return len(activeObjectQueue)<self.capacity and giverObject.haveToDispose(self)
......@@ -219,7 +220,7 @@ class Queue(CoreObject):
# sorts the Entities of the Queue according to the scheduling rule
# =======================================================================
def activeQSorter(self, criterion=None):
activeObjectQ=self.Res.activeQ
activeObjectQ=self.Res.users
if criterion==None:
criterion=self.schedulingRule
#if the schedulingRule is first in first out
......@@ -284,7 +285,7 @@ class Queue(CoreObject):
for obj in G.ObjList:
if obj.id in nextObjIds:
nextObject=obj
entity.nextQueueLength=len(nextObject.Res.activeQ)
entity.nextQueueLength=len(nextObject.Res.users)
activeObjectQ.sort(key=lambda x: x.nextQueueLength)
else:
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