Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
dream
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
1
Issues
1
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
dream
Commits
92e68215
Commit
92e68215
authored
May 27, 2014
by
Ioannis Papagiannopoulos
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
failure, objectInterruption, and queue updated
parent
a6618f51
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
51 additions
and
43 deletions
+51
-43
dream/simulation/CoreObject.py
dream/simulation/CoreObject.py
+1
-1
dream/simulation/Failure.py
dream/simulation/Failure.py
+12
-11
dream/simulation/ObjectInterruption.py
dream/simulation/ObjectInterruption.py
+18
-12
dream/simulation/Queue.py
dream/simulation/Queue.py
+20
-19
No files found.
dream/simulation/CoreObject.py
View file @
92e68215
...
...
@@ -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
...
...
dream/simulation/Failure.py
View file @
92e68215
...
...
@@ -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
.
getResourc
e
()
self
.
repairman
.
totalWorkingTime
+=
now
()
-
timeOperationStarted
self
.
repairman
.
getResource
().
releas
e
()
self
.
repairman
.
totalWorkingTime
+=
self
.
env
.
now
-
timeOperationStarted
# #===========================================================================
# # interrupts the victim
...
...
dream/simulation/ObjectInterruption.py
View file @
92e68215
...
...
@@ -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
.
s
ignal
(
now
()
)
self
.
isCalled
.
s
ucceed
(
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
dream/simulation/Queue.py
View file @
92e68215
...
...
@@ -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
,
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment