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
e066dd15
Commit
e066dd15
authored
May 07, 2014
by
Ioannis Papagiannopoulos
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Router now handles all operator assignement. Need to simplified and commented properly
parent
5b91c6cd
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
541 additions
and
369 deletions
+541
-369
dream/simulation/OperatorRouter.py
dream/simulation/OperatorRouter.py
+541
-369
No files found.
dream/simulation/OperatorRouter.py
View file @
e066dd15
...
@@ -25,7 +25,8 @@ Created on 19 Feb 2013
...
@@ -25,7 +25,8 @@ 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.Simulation
import
Simulation
from
SimPy.Simulation
import
Process
,
Resource
,
SimEvent
from
SimPy.Simulation
import
Process
,
Resource
,
SimEvent
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
...
@@ -47,7 +48,7 @@ class Router(ObjectInterruption):
...
@@ -47,7 +48,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
.
startCycle
=
SimEvent
(
'startCycle
'
)
self
.
isCalled
=
SimEvent
(
'RouterIsCalled
'
)
self
.
isInitialized
=
False
self
.
isInitialized
=
False
self
.
candidateOperators
=
[]
self
.
candidateOperators
=
[]
self
.
multipleCriterionList
=
[]
self
.
multipleCriterionList
=
[]
...
@@ -55,6 +56,12 @@ class Router(ObjectInterruption):
...
@@ -55,6 +56,12 @@ class Router(ObjectInterruption):
# boolean flag to check whether the Router should perform sorting on operators and on pendingEntities
# boolean flag to check whether the Router should perform sorting on operators and on pendingEntities
self
.
sorting
=
sorting
self
.
sorting
=
sorting
self
.
conflictingOperators
=
[]
self
.
conflictingOperators
=
[]
# list of objects to be signalled by the Router
self
.
toBeSignalled
=
[]
# flag to notify whether the router is already invoked
self
.
invoked
=
False
# flag to notify whether the router is dealing with managed or simple entities
self
.
managed
=
False
#===========================================================================
#===========================================================================
# the initialize method
# the initialize method
...
@@ -73,6 +80,9 @@ class Router(ObjectInterruption):
...
@@ -73,6 +80,9 @@ class Router(ObjectInterruption):
# flag used to check if the Router is initialised
# flag used to check if the Router is initialised
self
.
isInitialized
=
True
self
.
isInitialized
=
True
self
.
conflictingOperators
=
[]
self
.
conflictingOperators
=
[]
self
.
toBeSignalled
=
[]
self
.
invoked
=
False
self
.
managed
=
False
# =======================================================================
# =======================================================================
# the run method
# the run method
...
@@ -84,182 +94,118 @@ class Router(ObjectInterruption):
...
@@ -84,182 +94,118 @@ class Router(ObjectInterruption):
returns canAcceptAndIsRequested (inPositionToGet is True)
returns canAcceptAndIsRequested (inPositionToGet is True)
'''
'''
def
run
(
self
):
def
run
(
self
):
from
Globals
import
G
,
findObjectById
from
Globals
import
G
# find out whether we are dealing with managed entities
if
G
.
EntityList
:
for
entity
in
G
.
EntityList
:
if
entity
.
manager
:
self
.
managed
=
True
break
while
1
:
while
1
:
# wait until the router is called
# wait until the router is called
yield
waitevent
,
self
,
self
.
startCycle
yield
waitevent
,
self
,
self
.
isCalled
self
.
victim
=
findObjectById
(
self
.
startCycle
.
signalparam
)
# print '=-'*15
# yield waituntil,self,self.isCalled
# print 'router received event'
# when the router is called for the first time wait till all the entities
# wait till there are no more events, the machines must be blocked
# finished all their moves in stations of non-Machine-type
while
1
:
# before they can enter again a type-Machine object
# print Simulation.allEventNotices(sim)
yield
waituntil
,
self
,
self
.
entitiesFinishedMoving
if
now
()
in
Simulation
.
allEventTimes
(
sim
):
# update the objects to be served list (pendingObjects)
# print 'there are MORE events for now'
self
.
pendingObjects
=
[
object
for
object
in
G
.
MachineList
if
object
.
inPositionToGet
]
yield
hold
,
self
,
0
else
:
#===================================================================
# print 'there are NO more events for now'
# # TESTING
break
# print now(), '================================================================================'
# print '=-'*15
# print ' the pending objects are ', [str(object.id) for object in self.pendingObjects]
# after the events are over, assign the operators to machines for loading or simple processing
#===================================================================
# read the pendingEntities currentStations, these are the stations (queues) that may be signalled
# the activeCallers list is updated each time the canAcceptAndIsRequested returns true even if the machine is not signalled
# update the calledOperators list
# find the pending objects
self
.
calledOperators
=
[
operator
for
operator
in
G
.
OperatorsList
if
len
(
operator
.
activeCallersList
)]
self
.
findPendingObjects
()
# find the pending entities
#===================================================================
self
.
findPendingEntities
()
# # TESTING
# find the operators that can start working now
# print ' (calledOperators, activeCallers, callerEntities): ', [(str(operator.id),\
# [str(x.id) for x in operator.activeCallersList],\
# [str(x.giver.getActiveObjectQueue()[0].id)for x in operator.activeCallersList])\
# for operator in self.calledOperators]
#===================================================================
# find the operators that can start working now even if they are not called
self
.
findCandidateOperators
()
self
.
findCandidateOperators
()
#===================================================================
# # TESTING
# print ' {} the candidateOperators ',
# print [str(op.id) for op in self.candidateOperators]
# print [str(entity.id) for entity in G.pendingEntities]
#===================================================================
# sort the pendingEntities list
# sort the pendingEntities list
if
self
.
sorting
:
if
self
.
sorting
:
self
.
sortPendingEntities
()
self
.
sortPendingEntities
()
#===================================================================
# # TESTING
# print [str(entity.id) for entity in G.pendingEntities]
# if G.pendingEntities:
# print ' {} the pending entities that can proceed are: ',
# print [str(entity.id) for entity in G.pendingEntities if entity.canProceed]
#===================================================================
# find the operators candidateEntities
# find the operators candidateEntities
self
.
findCandidateEntities
()
self
.
findCandidateEntities
()
#===================================================================
# # TESTING
# print ' {} candidate entities for each candidateOperator ',
# print [(str(operator.id),[str(candidateEntity.id) for candidateEntity in operator.candidateEntities],)\
# for operator in self.candidateOperators]
#===================================================================
# find the entity that will occupy the resource, and the station that will receive it (if any available)
# find the entity that will occupy the resource, and the station that will receive it (if any available)
# entities that are already in stations have already a receiver
self
.
findCandidateReceivers
()
self
.
findCandidateReceivers
()
# assign operators to stations
self
.
assignOperators
()
# if an exit of an object is assigned to one station, while the operator to operate
# the moving entity is assigned to a different, unAssign the exit
#------------------------------------------------------------------------------
if
not
self
.
managed
:
for
operator
in
[
x
for
x
in
self
.
candidateOperators
if
x
.
isAssignedTo
()]:
if
not
operator
.
isAssignedTo
()
in
self
.
pendingObjects
:
for
object
in
[
x
for
x
in
operator
.
isAssignedTo
().
previous
if
x
.
exitIsAssignedTo
()]:
if
object
.
exitIsAssignedTo
()
!=
operator
.
isAssignedTo
():
object
.
unAssignExit
()
#------------------------------------------------------------------------------
else
:
for
operator
in
[
x
for
x
in
self
.
candidateOperators
if
x
.
isAssignedTo
()]:
if
not
operator
.
isAssignedTo
()
in
self
.
pendingObjects
:
if
operator
.
candidateEntity
.
currentStation
.
exitIsAssignedTo
():
if
operator
.
isAssignedTo
()
!=
operator
.
candidateEntity
.
currentStation
.
exitIsAssignedTo
():
operator
.
candidateEntity
.
currentStation
.
unAssignExit
()
# if an object cannot proceed with getEntity, unAssign the exit of its giver
for
object
in
self
.
pendingQueues
:
if
not
object
in
self
.
toBeSignalled
:
object
.
unAssignExit
()
# signal the stations that ought to be signalled
self
.
signalOperatedStations
()
#===================================================================
#===================================================================
# # TESTING
# # testing
# print ' {} (candidateOperator, candidateEntity, candidateReceiver) ',
# print 'router exiting'
# print [(str(op.id), str(op.candidateEntity.id), str(op.candidateEntity.candidateReceiver.id))\
# print '=-'*20
# for op in self.candidateOperators if op.candidateEntity.candidateReceiver]
#===================================================================
#===================================================================
self
.
exit
()
# sort the givers for the operators that will process the entities
self
.
sortGiverQueue
()
#===========================================================================
# for all the operators that are requested
# assigning operators to machines
for
operator
in
self
.
calledOperators
:
#===========================================================================
priorityObject
=
None
def
assignOperators
(
self
):
# check if the candidateReceivers are inPositionToGet and if they are already called
#------------------------------------------------------------------------------
try
:
# for all the operators that are requested
receiverIsActive
=
(
operator
.
candidateEntity
.
candidateReceiver
in
operator
.
activeCallersList
\
for
operator
in
self
.
candidateOperators
:
and
operator
.
candidateEntity
.
candidateReceiver
in
self
.
pendingObjects
)
# check if the candidateOperators are available, if the are requested and reside in the pendingObjects list
except
:
if
operator
.
checkIfResourceIsAvailable
():
receiverIsActive
=
True
# if the router deals with managed entities
#------------------------------------------------------------------------------
#===============================================================
if
not
self
.
managed
:
# # TESTING
# if the operator is not conflicting
# print ' calledOperator', operator.id,
if
not
operator
in
self
.
conflictingOperators
:
# print 'will receive?',operator.checkIfResourceIsAvailable() and receiverIsActive
# assign an operator to the priorityObject
#===============================================================
#=======================================================
# # testing
# check if the candidateOperators are available, if the are requested and reside in the pendingObjects list
# print 'router will assign', operator.id, 'to', operator.candidateStation.id
if
operator
.
checkIfResourceIsAvailable
()
and
\
#=======================================================
receiverIsActive
:
operator
.
assignTo
(
operator
.
candidateStation
)
# sort the activeCallersList of the operator
self
.
toBeSignalled
.
append
(
operator
.
candidateStation
)
operator
.
sortActiveCallers
()
#------------------------------------------------------------------------------
# find the activeCaller that has priority
else
:
priorityObject
=
next
(
x
for
x
in
operator
.
activeCallersList
if
x
in
self
.
pendingObjects
)
#===========================================================
# # TESTING
# print [str(caller.id) for caller in operator.activeCallersList]
# print ' the PRIORITY object is', priorityObject.id
#===========================================================
# and if the priorityObject is indeed pending
# and if the priorityObject is indeed pending
if
priorityObject
in
self
.
pendingObjects
:
if
(
operator
.
candidateEntity
.
currentStation
in
self
.
pendingObjects
)
and
(
not
operator
in
self
.
conflictingOperators
)
:
# assign an operator to the priorityObject
# assign an operator to the priorityObject
operator
.
operatorAssignedTo
=
priorityObject
#=======================================================
#=======================================================
# #
TESTING
# #
testing
# print
operator.id, 'got assigned to', priorityObject
.id
# print
'router will assign', operator.id, 'to', operator.candidateEntity.candidateReceiver
.id
#=======================================================
#=======================================================
operator
.
assignTo
(
operator
.
candidateEntity
.
candidateReceiver
)
# and let it proceed withGetEntity
self
.
toBeSignalled
.
append
(
operator
.
candidateEntity
.
currentStation
)
priorityObject
.
canProceedWithGetEntity
=
True
#===================================================================
priorityObject
.
inPositionToGet
=
False
# # testing
# if the are not called and they are not in the pendingObjects list clear their activeCallersList
# print 'router found objects to be signalled'
elif
not
receiverIsActive
:
# print [str(object.id) for object in self.toBeSignalled]
operator
.
activeCallersList
=
[]
# print [str(object.exitIsAssignedTo().id) for object in self.toBeSignalled if object.exitIsAssignedTo()]
# if an object cannot proceed with getEntity, unAssign the exit of its giver
#===================================================================
for
object
in
self
.
pendingObjects
:
if
not
object
.
canProceedWithGetEntity
:
object
.
giver
.
unAssignExit
()
#===================================================================
# # TESTING
# print ' these objects will proceed with getting entities',
# print [str(object.id) for object in self.pendingObjects if object.canProceedWithGetEntity]
#===================================================================
self
.
exit
()
#===========================================================================
# have the entities that have ended their processing when the router
# got first called finished their moves through queues?
#===========================================================================
def
entitiesFinishedMoving
(
self
):
# check if the entities waiting to be disposed from different Machines
# the first time the Router is called, have reached the last queue (if any)
# before the next Machine in their route
from
Globals
import
G
# pending entities are entities about to enter an other machine, updated by endProcessingActions()
# if there are any pending entities
if
len
(
G
.
pendingEntities
):
# local variable
allEntitiesMoved
=
False
# for each one of them
for
entity
in
G
.
pendingEntities
:
# if they are residing in a machine which waits to dispose and is functional
if
entity
.
currentStation
in
G
.
MachineList
:
if
entity
.
currentStation
.
checkIfMachineIsUp
()
\
and
entity
.
currentStation
.
waitToDispose
:
# if the next step in the entity's route is machine with Load operationType then continue
if
(
not
(
entity
.
currentStation
.
receiver
in
G
.
MachineList
)
\
and
entity
.
currentStation
.
receiver
.
canAccept
()
\
or
\
((
entity
.
currentStation
.
receiver
.
type
in
G
.
MachineList
)
\
and
not
any
(
type
==
'Load'
for
type
in
entity
.
currentStation
.
receiver
.
multOperationTypeList
))):
return
False
# if the entity is in a Queue
elif
entity
.
currentStation
in
G
.
QueueList
:
# if the hot flag of the entity is raised
if
entity
.
hot
:
allEntitiesMoved
=
True
# return True
else
:
return
False
elif
entity
.
currentStation
in
G
.
OrderDecompositionList
:
return
False
# TODO: this list can check all the available object in G.objList
# if no entity returned False then return True
if
allEntitiesMoved
:
return
True
return
True
# =======================================================================
# =======================================================================
# return control to the Machine.run
# return control to the Machine.run
# =======================================================================
# =======================================================================
...
@@ -268,49 +214,126 @@ class Router(ObjectInterruption):
...
@@ -268,49 +214,126 @@ class Router(ObjectInterruption):
# reset the variables that are used from the Router
# reset the variables that are used from the Router
for
operator
in
self
.
candidateOperators
:
for
operator
in
self
.
candidateOperators
:
operator
.
candidateEntities
=
[]
operator
.
candidateEntities
=
[]
operator
.
candidateStations
=
[]
operator
.
candidateStation
=
None
operator
.
candidateEntity
=
None
operator
.
candidateEntity
=
None
for
entity
in
G
.
pendingEntities
:
for
entity
in
G
.
pendingEntities
:
entity
.
canProceed
=
False
entity
.
canProceed
=
False
entity
.
candidateReceivers
=
[]
entity
.
candidateReceivers
=
[]
entity
.
candidateReceiver
=
None
entity
.
candidateReceiver
=
None
del
self
.
candidateOperators
[:]
del
self
.
candidateOperators
[:]
del
self
.
calledOperators
[:]
del
self
.
pendingObjects
[:]
del
self
.
pendingObjects
[:]
del
self
.
pendingMachines
[:]
del
self
.
pendingQueues
[:]
del
self
.
toBeSignalled
[:]
del
self
.
multipleCriterionList
[:]
del
self
.
multipleCriterionList
[:]
del
self
.
conflictingOperators
[:]
del
self
.
conflictingOperators
[:]
self
.
schedulingRule
=
'WT'
self
.
schedulingRule
=
'WT'
self
.
invoked
=
False
ObjectInterruption
.
exit
(
self
)
# self.victim.routerCycleOver.signal('router has implemented its logic')
#===========================================================================
#=======================================================================
# signal stations that wait for load operators
# Sort pendingEntities
#===========================================================================
# TODO: sorting them according to the operators schedulingRule
def
signalOperatedStations
(
self
):
#=======================================================================
# print 'router trying to signal pendingObjects'
def
sortPendingEntities
(
self
):
from
Globals
import
G
# TODO: to be used for sorting of operators
for
operator
in
self
.
candidateOperators
:
# there must be also a schedulingRule property for the Router
station
=
operator
.
isAssignedTo
()
# there must also be a way to have multiple criteria for the operators (eg MC-Priority-WT)
if
station
:
# WT may be needed to be applied everywhere
# if the router deals with simple entities
# TODO: move that piece of code elsewhere, it doesn't look nice here. and there is not point in doing it here
#------------------------------------------------------------------------------
# maybe it's better in findCandidateOperators method
if
not
self
.
managed
:
if
self
.
candidateOperators
:
assert
station
in
self
.
toBeSignalled
,
'the station must be in toBeSignalled list'
from
Globals
import
G
if
station
.
broker
.
waitForOperator
:
candidateList
=
G
.
pendingEntities
# signal this station's broker that the resource is available
self
.
activeQSorter
(
criterion
=
self
.
schedulingRule
,
candList
=
candidateList
)
#===========================================================
# # testing
#=======================================================================
# print now(), 'router signalling broker of', operator.isAssignedTo().id
# Sort candidateOperators
#===========================================================
# TODO: consider if there must be an argument set for the schedulingRules of the Router
station
.
broker
.
resourceAvailable
.
signal
(
now
())
# TODO: consider if the scheduling rule for the operators must be global for all of them
else
:
#=======================================================================
# signal the queue proceeding the station
def
sortOperators
(
self
):
if
station
.
canAccept
()
\
# TODO: there must be criteria for sorting the cadidateOperators
and
any
(
type
==
'Load'
for
type
in
station
.
multOperationTypeList
):
#if we have sorting according to multiple criteria we have to call the sorter many times
#=======================================================
# TODO: find out what happens in case of multiple criteria
# # testing
if
self
.
candidateOperators
:
# print now(), 'router signalling', operator.isAssignedTo().id
candidateList
=
self
.
candidateOperators
#=======================================================
self
.
activeQSorter
(
criterion
=
self
.
schedulingRule
,
candList
=
candidateList
)
station
.
loadOperatorAvailable
.
signal
(
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
#===========================================================
# # testing
# print now(), 'router signalling broker of', operator.isAssignedTo().id
#===========================================================
operator
.
isAssignedTo
().
broker
.
resourceAvailable
.
signal
(
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'
assert
operator
.
candidateEntity
.
currentStation
in
G
.
QueueList
,
'the candidateEntity currentStation to receive signal from Router is not a queue'
if
operator
.
candidateEntity
.
candidateReceiver
.
canAccept
()
\
and
any
(
type
==
'Load'
for
type
in
operator
.
candidateEntity
.
candidateReceiver
.
multOperationTypeList
):
#=======================================================
# # testing
# print now(), 'router signalling queue', operator.candidateEntity.currentStation.id
#=======================================================
operator
.
candidateEntity
.
currentStation
.
loadOperatorAvailable
.
signal
(
now
())
#===========================================================================
# clear the pending lists of the router
#===========================================================================
def
clearPending
(
self
):
self
.
pendingQueues
=
[]
self
.
pendingMachines
=
[]
self
.
pendingObjects
=
[]
#===========================================================================
# find the stations that can be signalled by the router
#===========================================================================
def
findPendingObjects
(
self
):
from
Globals
import
G
self
.
clearPending
()
for
entity
in
G
.
pendingEntities
:
for
machine
in
entity
.
currentStation
.
next
:
if
any
(
type
==
'Load'
for
type
in
machine
.
multOperationTypeList
):
self
.
pendingQueues
.
append
(
entity
.
currentStation
)
self
.
pendingObjects
.
append
(
entity
.
currentStation
)
break
self
.
pendingMachines
=
[
machine
for
machine
in
G
.
MachineList
if
machine
.
broker
.
waitForOperator
]
self
.
pendingObjects
=
self
.
pendingQueues
+
self
.
pendingMachines
#=======================================================================
# # testing
# print 'router found pending objects'
# print [object.id for object in self.pendingObjects]
#=======================================================================
#===========================================================================
# finding the entities that require manager now
#===========================================================================
def
findPendingEntities
(
self
):
from
Globals
import
G
self
.
pending
=
[]
# list of entities that are pending
for
machine
in
self
.
pendingMachines
:
self
.
pending
.
append
(
machine
.
currentEntity
)
for
entity
in
G
.
pendingEntities
:
for
machine
in
entity
.
currentStation
.
next
:
if
any
(
type
==
'Load'
for
type
in
machine
.
multOperationTypeList
):
self
.
pending
.
append
(
entity
)
break
# find out which type of entities are we dealing with, managed entities or not
if
self
.
pending
:
if
self
.
pending
[
0
].
manager
:
self
.
managed
=
True
#=======================================================================
# # testing
# print 'found pending entities'
# print [entity.id for entity in self.pending if not entity.type=='Part']
#=======================================================================
#========================================================================
#========================================================================
# Find candidate Operators
# Find candidate Operators
...
@@ -321,38 +344,72 @@ class Router(ObjectInterruption):
...
@@ -321,38 +344,72 @@ class Router(ObjectInterruption):
# . the candidate receivers of the entities (the stations the operators will be working at)
# . the candidate receivers of the entities (the stations the operators will be working at)
#========================================================================
#========================================================================
def
findCandidateOperators
(
self
):
def
findCandidateOperators
(
self
):
#TODO: here check the case of no managed entities (normal machines)
from
Globals
import
G
from
Globals
import
G
# if there are pendingEntities
# if we are not dealing with managed entities
if
len
(
G
.
pendingEntities
):
#------------------------------------------------------------------------------
# for those pending entities that require a manager (MachineManagedJob case)
if
not
self
.
managed
:
for
entity
in
[
x
for
x
in
G
.
pendingEntities
if
x
.
manager
]:
# if there are pendingEntities
# if the entity is ready to move to a machine and its manager is available
if
self
.
pendingObjects
:
if
entity
.
hot
and
entity
.
manager
.
checkIfResourceIsAvailable
():
for
object
in
self
.
pendingObjects
:
# for entities of type OrderComponent, if they reside at a conditionalBuffer,
if
object
in
self
.
pendingMachines
:
# they must wait till their basicsEnded flag is raised
if
object
.
operatorPool
.
checkIfResourceIsAvailable
():
if
entity
.
type
==
'OrderComponent'
:
candidateOperator
=
object
.
operatorPool
.
findAvailableOperator
()
from
ConditionalBuffer
import
ConditionalBuffer
# TODO: this way no sorting is performed
if
(
entity
.
componentType
==
'Secondary'
\
if
not
candidateOperator
in
self
.
candidateOperators
:
and
type
(
entity
.
currentStation
)
is
ConditionalBuffer
\
self
.
candidateOperators
.
append
(
candidateOperator
)
and
entity
.
order
.
basicsEnded
==
False
):
candidateOperator
.
candidateStations
.
append
(
object
)
continue
elif
object
in
self
.
pendingQueues
:
# unassembled components of a mould must wait at a MouldAssemblyBuffer till the componentsReadyForAssembly flag is raised
for
nextobject
in
object
.
next
:
from
MouldAssemblyBuffer
import
MouldAssemblyBuffer
if
nextobject
.
canAccept
(
object
):
if
type
(
entity
.
currentStation
)
is
MouldAssemblyBuffer
:
candidateOperator
=
nextobject
.
operatorPool
.
findAvailableOperator
()
if
not
entity
.
order
.
componentsReadyForAssembly
:
if
not
candidateOperator
in
self
.
candidateOperators
:
continue
self
.
candidateOperators
.
append
(
candidateOperator
)
# for all the possible receivers of an entity check whether they can accept and then set accordingly the canProceed flag of the entity
candidateOperator
.
candidateStations
.
append
(
object
)
for
nextObject
in
[
object
for
object
in
entity
.
currentStation
.
next
if
object
.
canAcceptEntity
(
entity
)]:
# update the schedulingRule/multipleCriterionList of the Router
entity
.
canProceed
=
True
if
self
.
sorting
:
entity
.
candidateReceivers
.
append
(
nextObject
)
self
.
updateSchedulingRule
()
# if the entity can proceed, add its manager to the candidateOperators list
# in case the router deals with managed entities
if
entity
.
canProceed
and
not
entity
.
manager
in
self
.
candidateOperators
:
#------------------------------------------------------------------------------
self
.
candidateOperators
.
append
(
entity
.
manager
)
else
:
# update the schedulingRule/multipleCriterionList of the Router
# if there are pendingEntities
if
self
.
sorting
:
if
len
(
self
.
pending
):
self
.
updateSchedulingRule
()
# for those pending entities that require a manager (MachineManagedJob case)
for
entity
in
[
x
for
x
in
self
.
pending
if
x
.
manager
]:
# if the entity is ready to move to a machine and its manager is available
if
entity
.
manager
.
checkIfResourceIsAvailable
():
# for entities of type OrderComponent, if they reside at a conditionalBuffer,
# they must wait till their basicsEnded flag is raised
if
entity
.
type
==
'OrderComponent'
:
from
ConditionalBuffer
import
ConditionalBuffer
if
(
entity
.
componentType
==
'Secondary'
\
and
type
(
entity
.
currentStation
)
is
ConditionalBuffer
\
and
entity
.
order
.
basicsEnded
==
False
):
continue
# unassembled components of a mould must wait at a MouldAssemblyBuffer till the componentsReadyForAssembly flag is raised
from
MouldAssemblyBuffer
import
MouldAssemblyBuffer
if
type
(
entity
.
currentStation
)
is
MouldAssemblyBuffer
:
if
not
entity
.
order
.
componentsReadyForAssembly
:
continue
# for all the possible receivers of an entity check whether they can accept and then set accordingly the canProceed flag of the entity
for
nextObject
in
[
object
for
object
in
entity
.
currentStation
.
next
if
object
.
canAcceptEntity
(
entity
)]:
entity
.
canProceed
=
True
entity
.
candidateReceivers
.
append
(
nextObject
)
# if the entity is in a machines who's broker waits for operator then
if
entity
.
currentStation
in
self
.
pendingMachines
:
entity
.
canProceed
=
True
# if the entity can proceed, add its manager to the candidateOperators list
if
entity
.
canProceed
and
not
entity
.
manager
in
self
.
candidateOperators
:
self
.
candidateOperators
.
append
(
entity
.
manager
)
# update the schedulingRule/multipleCriterionList of the Router
if
self
.
sorting
:
self
.
updateSchedulingRule
()
#=======================================================================
# # testing
# print 'router found candidate operators'
# print [operator.id for operator in self.candidateOperators]
#=======================================================================
#=======================================================================
#=======================================================================
# find the schedulingRules of the candidateOperators
# find the schedulingRules of the candidateOperators
#=======================================================================
#=======================================================================
...
@@ -371,7 +428,7 @@ class Router(ObjectInterruption):
...
@@ -371,7 +428,7 @@ class Router(ObjectInterruption):
assert
len
(
self
.
multipleCriterionList
)
==
1
,
'The operators must have the same (one) scheduling rule'
assert
len
(
self
.
multipleCriterionList
)
==
1
,
'The operators must have the same (one) scheduling rule'
if
len
(
self
.
multipleCriterionList
)
==
1
:
if
len
(
self
.
multipleCriterionList
)
==
1
:
self
.
schedulingRule
=
self
.
multipleCriterionList
[
0
]
self
.
schedulingRule
=
self
.
multipleCriterionList
[
0
]
#=======================================================================
#=======================================================================
# Find the candidateEntities for each candidateOperator
# Find the candidateEntities for each candidateOperator
# find the candidateEntities of each candidateOperator and sort them according
# find the candidateEntities of each candidateOperator and sort them according
...
@@ -380,160 +437,275 @@ class Router(ObjectInterruption):
...
@@ -380,160 +437,275 @@ class Router(ObjectInterruption):
#=======================================================================
#=======================================================================
def
findCandidateEntities
(
self
):
def
findCandidateEntities
(
self
):
from
Globals
import
G
from
Globals
import
G
# TODO: sort according to the number of pending Jobs
# if the moving entities are not managed
# TODO Have to sort again according to the priority used by the operators
#------------------------------------------------------------------------------
if
not
self
.
managed
:
# initialise the operatorsWithOneOption and operatorsWithOneCandidateEntity lists
# TODO: the operator finds no entities in this case
operatorsWithOneOption
=
[]
# initialise operatorsWithOneCandidateStation lists
operatorsWithOneCandidateEntity
=
[]
operatorsWithOneCandidateStation
=
[]
# for all the candidateOperators
# for all the candidateOperators
for
operator
in
self
.
candidateOperators
:
for
operator
in
self
.
candidateOperators
:
# find which pendingEntities that can move to machines is the operator managing
# sort the candidate operators so that those who have only one option be served first
for
entity
in
[
x
for
x
in
G
.
pendingEntities
if
x
.
canProceed
and
x
.
manager
==
operator
]:
if
len
(
operator
.
candidateStations
)
==
1
:
operator
.
candidateEntities
.
append
(
entity
)
operatorsWithOneCandidateStation
.
append
(
operator
)
# sort the candidate operators so that those who have only one option be served first
if
len
(
operator
.
candidateEntities
)
==
1
:
# TODO: the operator here actually chooses entity. This may pose a problem as two entities may be equivalent
operatorsWithOneCandidateEntity
.
append
(
operator
)
# and as the operators chooses the sorting of the queue (if they do reside in the same queue is not taken into account)
# if the candidate entity has only one receiver then append the operator to operatorsWithOneOption list
# sort the candidateEntities list of each operator according to its schedulingRule
if
len
(
operator
.
candidateEntities
[
0
].
candidateReceivers
)
==
1
:
# TODO: rename the sorting method, the simple operator is not sorting entities but candidateStations
operatorsWithOneOption
.
append
(
operator
)
for
operator
in
[
x
for
x
in
self
.
candidateOperators
if
x
.
candidateStations
]:
operator
.
sortCandidateEntities
()
# TODO: the operator here actually chooses entity. This may pose a problem as two entities may be equivalent
# and as the operators chooses the sorting of the queue (if they do reside in the same queue is not taken into account)
# if there operators that have only one option then sort the candidateOperators according to the first one of these
# sort the candidateEntities list of each operator according to its schedulingRule
# TODO: find out what happens if there are many operators with one option
for
operator
in
[
x
for
x
in
self
.
candidateOperators
if
x
.
candidateEntities
]:
# TODO: incorporate that to
operator
.
sortCandidateEntities
()
# self.sortOperators()
# if there operators that have only one option then sort the candidateOperators according to the first one of these
if
self
.
sorting
:
# TODO: find out what happens if there are many operators with one option
# sort the operators according to their waiting time
# TODO: incorporate that to
self
.
candidateOperators
.
sort
(
key
=
lambda
x
:
x
.
totalWorkingTime
)
# self.sortOperators()
# sort according to the number of options
if
operatorsWithOneCandidateStation
:
if
self
.
sorting
:
self
.
candidateOperators
.
sort
(
key
=
lambda
x
:
x
in
operatorsWithOneCandidateStation
,
reverse
=
True
)
# sort the operators according to their waiting time
# if the entities are managed
self
.
candidateOperators
.
sort
(
key
=
lambda
x
:
x
.
totalWorkingTime
)
#------------------------------------------------------------------------------
# sort according to the number of options
else
:
if
operatorsWithOneOption
:
# TODO: sort according to the number of pending Jobs
self
.
candidateOperators
.
sort
(
key
=
lambda
x
:
x
in
operatorsWithOneOption
,
reverse
=
True
)
# TODO Have to sort again according to the priority used by the operators
# initialise the operatorsWithOneOption and operatorsWithOneCandidateEntity lists
operatorsWithOneOption
=
[]
operatorsWithOneCandidateEntity
=
[]
# for all the candidateOperators
for
operator
in
self
.
candidateOperators
:
# find which pendingEntities that can move to machines is the operator managing
for
entity
in
[
x
for
x
in
self
.
pending
if
x
.
canProceed
and
x
.
manager
==
operator
]:
operator
.
candidateEntities
.
append
(
entity
)
# sort the candidate operators so that those who have only one option be served first
if
len
(
operator
.
candidateEntities
)
==
1
:
operatorsWithOneCandidateEntity
.
append
(
operator
)
# if the candidate entity has only one receiver then append the operator to operatorsWithOneOption list
if
len
(
operator
.
candidateEntities
[
0
].
candidateReceivers
)
==
1
:
operatorsWithOneOption
.
append
(
operator
)
# TODO: the operator here actually chooses entity. This may pose a problem as two entities may be equivalent
# and as the operators chooses the sorting of the queue (if they do reside in the same queue is not taken into account)
# sort the candidateEntities list of each operator according to its schedulingRule
for
operator
in
[
x
for
x
in
self
.
candidateOperators
if
x
.
candidateEntities
]:
operator
.
sortCandidateEntities
()
# if there operators that have only one option then sort the candidateOperators according to the first one of these
# TODO: find out what happens if there are many operators with one option
# TODO: incorporate that to
# self.sortOperators()
if
self
.
sorting
:
# sort the operators according to their waiting time
self
.
candidateOperators
.
sort
(
key
=
lambda
x
:
x
.
totalWorkingTime
)
# sort according to the number of options
if
operatorsWithOneOption
:
self
.
candidateOperators
.
sort
(
key
=
lambda
x
:
x
in
operatorsWithOneOption
,
reverse
=
True
)
#=======================================================================
# # testing
# print 'router found the candidate entities for each operator'
# print [(str(operator.id),\
# [str(x.id) for x in operator.candidateEntities])
# for operator in self.candidateOperators]
#=======================================================================
#=======================================================================
# Sort pendingEntities
# TODO: sorting them according to the operators schedulingRule
#=======================================================================
def
sortPendingEntities
(
self
):
# TODO: to be used for sorting of operators
# there must be also a schedulingRule property for the Router
# there must also be a way to have multiple criteria for the operators (eg MC-Priority-WT)
# WT may be needed to be applied everywhere
# TODO: move that piece of code elsewhere, it doesn't look nice here. and there is not point in doing it here
# maybe it's better in findCandidateOperators method
if
self
.
candidateOperators
:
from
Globals
import
G
candidateList
=
self
.
pending
self
.
activeQSorter
(
criterion
=
self
.
schedulingRule
,
candList
=
candidateList
)
#=======================================================================
# # testing
# print 'router sorted pending entities'
#=======================================================================
#=======================================================================
# Sort candidateOperators
# TODO: consider if there must be an argument set for the schedulingRules of the Router
# TODO: consider if the scheduling rule for the operators must be global for all of them
#=======================================================================
def
sortOperators
(
self
):
# TODO: there must be criteria for sorting the cadidateOperators
#if we have sorting according to multiple criteria we have to call the sorter many times
# TODO: find out what happens in case of multiple criteria
if
self
.
candidateOperators
:
candidateList
=
self
.
candidateOperators
self
.
activeQSorter
(
criterion
=
self
.
schedulingRule
,
candList
=
candidateList
)
#=======================================================================
#=======================================================================
# Find candidate entities and their receivers
# Find candidate entities and their receivers
# TODO: if there is a critical entity, its manager should be served first
# TODO: if there is a critical entity, its manager should be served first
# TODO: have to sort again after choosing candidateEntity
# TODO: have to sort again after choosing candidateEntity
#=======================================================================
#=======================================================================
def
findCandidateReceivers
(
self
):
def
findCandidateReceivers
(
self
):
# initialise local variables occupiedReceivers and entitiesWithOccupiedReceivers
if
not
self
.
managed
:
conflictingOperators
=
[]
# list with the operators that have candidateEntity with conflicting candidateReceivers
# initialise local variables occupiedReceivers and entitiesWithOccupiedReceivers
conflictingEntities
=
[]
# entities with conflictingReceivers
conflictingStations
=
[]
# list with the operators that have candidateEntity with conflicting candidateReceivers
occupiedReceivers
=
[]
# occupied candidateReceivers of a candidateEntity
conflictingOperators
=
[]
entitiesWithOccupiedReceivers
=
[]
# list of entities that have no available receivers
# finally we have to sort before giving the entities to the operators
# finally we have to sort before giving the entities to the operators
# If there is an entity which must have priority then it should be assigned first
# If there is an entity which must have priority then it should be assigned first
#local method that finds a candidate entity for an operator
#local method that finds a candidate entity for an operator
def
findCandidateStation
():
def
findCandidateEntity
():
candidateStation
=
next
(
x
for
x
in
operator
.
candidateStations
if
not
x
in
conflictingStations
)
candidateEntity
=
next
(
x
for
x
in
operator
.
candidateEntities
if
not
x
in
entitiesWithOccupiedReceivers
)
if
not
self
.
sorting
:
if
not
candidateStation
:
candidateStation
=
next
(
x
for
x
in
operator
.
candidateStations
)
conflictingStations
.
append
(
candidateStation
)
return
candidateStation
# TODO: sorting again after choosing candidateEntity
if
self
.
sorting
:
self
.
sortOperators
()
# for the candidateOperators that do have candidateEntities pick a candidateEntity
for
operator
in
[
x
for
x
in
self
.
candidateOperators
if
x
.
candidateStations
]:
# find the first available entity that has no occupied receivers
operator
.
candidateStation
=
findCandidateStation
()
# find the resources that are 'competing' for the same station
if
not
self
.
sorting
:
if
not
self
.
sorting
:
if
not
candidateEntity
:
# if there are entities that have conflicting receivers
candidateEntity
=
next
(
x
for
x
in
operator
.
candidateEntities
)
if
len
(
conflictingStations
):
conflictingEntities
.
append
(
candidateEntity
)
for
operator
in
self
.
candidateOperators
:
return
candidateEntity
if
operator
.
candidateStation
in
conflictingStations
:
conflictingOperators
.
append
(
operator
)
#local method that finds a receiver for a candidate entity
self
.
conflictingOperators
=
conflictingOperators
def
findCandidateReceiver
():
# keep the sorting provided by the queues if there is conflict between operators
# find the receiver that waits the most
conflictingGroup
=
[]
# list that holds the operators that have the same recipient
def
chooseReceiverFrom
(
list
):
if
not
self
.
sorting
and
self
.
conflictingOperators
:
maxTimeWaiting
=
0
# for each of the candidateReceivers
for
object
in
list
:
for
station
in
conflictingStations
:
timeWaiting
=
now
()
-
object
.
timeLastEntityLeft
# find the group of operators that compete for this station
if
(
timeWaiting
>
maxTimeWaiting
or
maxTimeWaiting
==
0
):
conflictingGroup
=
[
operator
for
operator
in
self
.
conflictingOperators
if
operator
.
candidateStation
==
station
]
maxTimeWaiting
=
timeWaiting
# the operator that can proceed is the manager of the entity as sorted by the queue that holds them
receiver
=
object
conflictingGroup
.
sort
()
return
receiver
# the operators that are not first in the list cannot proceed
# initiate the local list variable available receivers
for
operator
in
conflitingGroup
:
availableReceivers
=
[
x
for
x
in
operator
.
candidateEntity
.
candidateReceivers
\
if
conflictingGroup
.
index
(
operator
)
!=
0
:
if
not
x
in
occupiedReceivers
]
self
.
candidateOperators
.
remove
(
operator
)
# and pick the object that is waiting for the most time
self
.
calledOperators
.
remove
(
operator
)
if
availableReceivers
:
# TODO: must find the receiver that waits the most
availableReceiver
=
chooseReceiverFrom
(
availableReceivers
)
occupiedReceivers
.
append
(
availableReceiver
)
# if there is no available receiver add the entity to the entitiesWithOccupiedReceivers list
else
:
entitiesWithOccupiedReceivers
.
append
(
operator
.
candidateEntity
)
availableReceiver
=
None
# if the sorting flag is not set then the sorting of each queue must prevail in case of operators conflict
if
not
self
.
sorting
and
not
availableReceiver
and
availableReceivers
:
availableReceiver
=
chooseReceiverFrom
(
operator
.
candidateEntity
.
candidateReceivers
)
return
availableReceiver
# if the moving entities are managed
#------------------------------------------------------------------------------
else
:
# initialise local variables occupiedReceivers and entitiesWithOccupiedReceivers
conflictingOperators
=
[]
# list with the operators that have candidateEntity with conflicting candidateReceivers
conflictingEntities
=
[]
# entities with conflictingReceivers
occupiedReceivers
=
[]
# occupied candidateReceivers of a candidateEntity
entitiesWithOccupiedReceivers
=
[]
# list of entities that have no available receivers
# finally we have to sort before giving the entities to the operators
# If there is an entity which must have priority then it should be assigned first
#local method that finds a candidate entity for an operator
def
findCandidateEntity
():
candidateEntity
=
next
(
x
for
x
in
operator
.
candidateEntities
if
not
x
in
entitiesWithOccupiedReceivers
)
if
not
self
.
sorting
:
if
not
candidateEntity
:
candidateEntity
=
next
(
x
for
x
in
operator
.
candidateEntities
)
conflictingEntities
.
append
(
candidateEntity
)
return
candidateEntity
#local method that finds a receiver for a candidate entity
def
findCandidateReceiver
():
# find the receiver that waits the most
def
chooseReceiverFrom
(
list
):
maxTimeWaiting
=
0
for
object
in
list
:
timeWaiting
=
now
()
-
object
.
timeLastEntityLeft
if
(
timeWaiting
>
maxTimeWaiting
or
maxTimeWaiting
==
0
):
maxTimeWaiting
=
timeWaiting
receiver
=
object
return
receiver
# initiate the local list variable available receivers
availableReceivers
=
[
x
for
x
in
operator
.
candidateEntity
.
candidateReceivers
\
if
not
x
in
occupiedReceivers
]
# and pick the object that is waiting for the most time
if
availableReceivers
:
# TODO: must find the receiver that waits the most
availableReceiver
=
chooseReceiverFrom
(
availableReceivers
)
occupiedReceivers
.
append
(
availableReceiver
)
# if there is no available receiver add the entity to the entitiesWithOccupiedReceivers list
else
:
entitiesWithOccupiedReceivers
.
append
(
operator
.
candidateEntity
)
availableReceiver
=
None
# if the sorting flag is not set then the sorting of each queue must prevail in case of operators conflict
if
not
self
.
sorting
and
not
availableReceiver
and
availableReceivers
:
availableReceiver
=
chooseReceiverFrom
(
operator
.
candidateEntity
.
candidateReceivers
)
return
availableReceiver
# TODO: sorting again after choosing candidateEntity
if
self
.
sorting
:
self
.
sortOperators
()
# for the candidateOperators that do have candidateEntities pick a candidateEntity
for
operator
in
[
x
for
x
in
self
.
candidateOperators
if
x
.
candidateEntities
]:
# find the first available entity that has no occupied receivers
operator
.
candidateEntity
=
findCandidateEntity
()
if
operator
.
candidateEntity
:
if
operator
.
candidateEntity
.
currentStation
in
self
.
pendingMachines
:
operator
.
candidateEntity
.
candidateReceiver
=
operator
.
candidateEntity
.
currentStation
else
:
operator
.
candidateEntity
.
candidateReceiver
=
findCandidateReceiver
()
# find the resources that are 'competing' for the same station
if
not
self
.
sorting
:
# if there are entities that have conflicting receivers
if
len
(
conflictingEntities
):
for
operator
in
self
.
candidateOperators
:
if
operator
.
candidateEntity
in
conflictingEntities
:
conflictingOperators
.
append
(
operator
)
elif
operator
.
candidateEntity
.
candidateReceiver
in
[
x
.
candidateReceiver
for
x
in
conflinctingEntities
]:
conflictingOperators
.
append
(
operator
)
self
.
conflictingOperators
=
conflictingOperators
# keep the sorting provided by the queues if there is conflict between operators
conflictingGroup
=
[]
# list that holds the operators that have the same recipient
if
not
self
.
sorting
and
self
.
conflictingOperators
:
# for each of the candidateReceivers
for
receiver
in
[
x
.
candidateEntity
.
candidateReceiver
for
x
in
self
.
conflictingOperators
]:
# find the group of operators that compete for this station
conflictingGroup
=
[
operator
for
operator
in
self
.
conflictingOperators
if
operator
.
candidateEntity
.
candidateReceiver
==
receiver
]
assert
len
([
station
for
station
in
[
x
.
candidateEntity
.
currentStation
for
x
in
conflictingGroup
]]),
\
'the conflicting entities must reside in the same queue'
# for each of the competing for the same station operators
for
operator
in
conflictingGroup
:
# find the index of entities to be operated by them in the queue that holds them
operator
.
ind
=
operator
.
candidateEntity
.
currentStation
.
getActiveObjectQueue
().
index
(
operator
.
candidateEntity
)
# the operator that can proceed is the manager of the entity as sorted by the queue that holds them
conflictingGroup
.
sort
(
key
=
lambda
x
:
x
.
ind
)
# the operators that are not first in the list cannot proceed
for
operator
in
conflitingGroup
:
if
conflictingGroup
.
index
(
operator
)
!=
0
:
self
.
candidateOperators
.
remove
(
operator
)
self
.
calledOperators
.
remove
(
operator
)
# TODO: sorting again after choosing candidateEntity
#=======================================================================
if
self
.
sorting
:
# # testing
self
.
sortOperators
()
# print 'router found candidate receivers for each entity'
# print [(str(entity.id),\
# for the candidateOperators that do have candidateEntities pick a candidateEntity
# str(entity.candidateReceiver.id))
for
operator
in
[
x
for
x
in
self
.
candidateOperators
if
x
.
candidateEntities
]:
# for entity in self.pending if entity.candidateReceiver]
# find the first available entity that has no occupied receivers
#=======================================================================
operator
.
candidateEntity
=
findCandidateEntity
()
if
operator
.
candidateEntity
:
operator
.
candidateEntity
.
candidateReceiver
=
findCandidateReceiver
()
# find the resources that are 'competing' for the same station
if
not
self
.
sorting
:
# if there are entities that have conflicting receivers
if
len
(
conflictingEntities
):
for
operator
in
self
.
candidateOperators
:
if
operator
.
candidateEntity
in
conflictingEntities
:
conflictingOperators
.
append
(
operator
)
elif
operator
.
candidateEntity
.
candidateReceiver
in
[
x
.
candidateReceiver
for
x
in
conflinctingEntities
]:
conflictingOperators
.
append
(
operator
)
self
.
conflictingOperators
=
conflictingOperators
# keep the sorting provided by the queues if there is conflict between operators
conflictingGroup
=
[]
# list that holds the operators that have the same recipient
if
not
self
.
sorting
and
self
.
conflictingOperators
:
# for each of the candidateReceivers
for
receiver
in
[
x
.
candidateEntity
.
candidateReceiver
for
x
in
self
.
conflictingOperators
]:
# find the group of operators that compete for this station
conflictingGroup
=
[
operator
for
operator
in
self
.
conflictingOperators
if
operator
.
candidateEntity
.
candidateReceiver
==
receiver
]
assert
len
([
station
for
station
in
[
x
.
candidateEntity
.
currentStation
for
x
in
conflictingGroup
]]),
\
'the conflicting entities must reside in the same queue'
# for each of the competing for the same station operators
for
operator
in
conflictingGroup
:
# find the index of entities to be operated by them in the queue that holds them
operator
.
ind
=
operator
.
candidateEntity
.
currentStation
.
getActiveObjectQueue
().
index
(
operator
.
candidateEntity
)
# the operator that can proceed is the manager of the entity as sorted by the queue that holds them
conflictingGroup
.
sort
(
key
=
lambda
x
:
x
.
ind
)
# the operators that are not first in the list cannot proceed
for
operator
in
conflitingGroup
:
if
conflictingGroup
.
index
(
operator
)
!=
0
:
self
.
candidateOperators
.
remove
(
operator
)
self
.
calledOperators
.
remove
(
operator
)
#=======================================================================
# Sort Givers
# TODO: the queues of the candidate givers are sorted only if their receiver is not in activeCallersList
# if an operator is called the control returns to the generator of the Router (run())
# the next objects are not checked
# They must be control
#=======================================================================
def
sortGiverQueue
(
self
):
# for those operators that do have candidateEntity
for
operator
in
[
x
for
x
in
self
.
candidateOperators
if
x
.
candidateEntity
]:
# check whether are called by objects that require the resource
operator
.
called
=
(
operator
in
self
.
calledOperators
)
# if they are not called or are not in the pendingObjects list sort the queues of the
# of the requesting the operator entities.
if
not
operator
.
called
:
operator
.
candidateEntity
.
currentStation
.
sortEntitiesForOperator
(
operator
)
# TODO: if the first candidate is not called then must run again
# if the first is called then this one must proceed with get entity
elif
not
operator
.
candidateEntity
.
candidateReceiver
in
self
.
pendingObjects
:
operator
.
candidateEntity
.
currentStation
.
sortEntitiesForOperator
(
operator
)
else
:
break
# =======================================================================
# =======================================================================
# sorts the Operators of the Queue according to the scheduling rule
# sorts the Operators of the Queue according to the scheduling rule
# =======================================================================
# =======================================================================
...
...
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