Pallet preparation - Preemption no restart¶
SimPype features used in this example: Random variables, Resource custom model, Pipe custom model, Log custom message properties.
The scenario of the simulation is the following:
|Urgent order| -\
) -> |Worker|
|Normal order| -/
This example models a working day (8 hours) of a worker
in a warehouse.
The worker’s job is to prepare a pallet upon receiving an order.
There are two types of orders:
- Urgent
- Normal
Each order comprises a number of items to be packed on the same pallet.
Urgent orders preempt
normal orders.
This means that if an urgent order is received while the worker is preparing the pallet for a normal order, the worker will stop what is doing and will immedietaly start preparing the pallet for the urgent order.
Once the urgent pallet is prepare, the worker will resume the preparation of the pallet of the normal order.
This kind of interaction is usually called preemption with no restart.
The scenario is so implemented with SimPype:
import simpype
import random
# [Mandatory] Create a SimPype simulation object
sim = simpype.Simulation(id = 'pallet_norestart')
# [Optional] Fix the seed used by the pseudo-random generator
sim.seed = 42
# [Optional] Configure the log directory.
# [Default] Log are store by default in the 'current working directory/log'
sim.log.dir = 'log'
# [Optional] Disable the logging to file and print to console instead
#sim.log.file = False
#sim.log.print = True
# [Optional] Log custom message properties
sim.log.property('items')
# [Optional] Configure the path containting the models for the simulation.
# [Default] Current working directory
sim.model.dir = 'examples/model'
# Create a generator
urgent = sim.add_generator(id = 'urgent')
# Assign an arrival time
urgent.random['arrival'] = {
0: lambda: random.expovariate(1.0 / 3600)
}
urgent.message.property['priority'] = 'urgent'
urgent.message.property['items'] = {
0: lambda: random.randint(1, 5)
}
# Create a generator
normal = sim.add_generator(id = 'normal')
# Assign an arrival time
normal.random['arrival'] = {
0: lambda: random.expovariate(1.0 / 300)
}
normal.message.property['priority'] = 'normal'
normal.message.property['items'] = {
0: lambda: random.randint(10, 30)
}
# Add a resource
worker = sim.add_resource(id = 'worker', model = 'r_preemption', pipe = 'p_preemption')
worker.random['service'] = {
0: lambda: random.expovariate(1.0 / 10)
}
# Add a pipeline connecting the generator to the resource
p0 = sim.add_pipeline(urgent, worker)
p1 = sim.add_pipeline(normal, worker)
# Run until t=28800 (8 hours)
sim.run(until = 28800)
Where pipe model p_preemption
is so implemented:
import simpype
class PriorityPreemption(simpype.Pipe):
def __init__(self, sim, resource, id):
super().__init__(sim, resource, id)
self.add_queue(id = 'preempted')
self.add_queue(id = 'urgent')
self.add_queue(id = 'normal')
@simpype.pipe.dequeue
def dequeue(self):
if len(self.queue['urgent']) > 0:
return self.queue['urgent'].pop()
elif len(self.queue['preempted']) > 0:
return self.queue['preempted'].pop()
else:
return self.queue['normal'].pop()
@simpype.pipe.enqueue
def enqueue(self, message):
if message.property['priority'].value == 'urgent':
m = self.queue['urgent'].push(message)
tlist = [t for t in self.resource.task.values() if t.process.is_alive and t.message.property['priority'].value != 'urgent']
# If the resource is busy, preempt the current task
if len(tlist) > 0:
#task = max(tlist, key = lambda task: task.message.property['priority'].value)
task = tlist[0]
task.interrupt(cause = 'preempted')
# This if is useful only in case of preemption with no restart
if 'wait' in task.message.property:
task.message.property['wait'] = task.message.property['wait'].value - (task.interrupted - task.started)
self.queue['preempted'].push(task.message)
else:
m = self.queue['normal'].push(message)
return m
# Do NOT remove
pipe = lambda *args: PriorityPreemption(*args)
And resource model r_preemption
is so implemented:
import simpype
class ResourcePreemption(simpype.Resource):
def __init__(self, sim, id, capacity = 1, pipe = None):
super().__init__(sim, id, capacity, pipe)
# This is overwritten later in the simulaiton file
self.random['service'] = {
0: lambda: 1.0
}
@simpype.resource.service
def service(self, message):
if 'wait' not in message.property:
message.property['wait'] = message.property['items'].value * self.random['service'].value
yield self.env.timeout(message.property['wait'].value)
# Do NOT remove
resource = lambda *args: ResourcePreemption(*args)
sim.cfg
stored under the log
folder contains:
Simulation Seed: 42
Simulation Time: 28800.000000000
Execution Time: 0.060198644
sim.log
stored under the log
folder contains:
timestamp,message,seq_num,resource,event,items
27.285721382,normal,0,worker,pipe.in,23
27.285721382,normal,0,worker,pipe.out,23
36.975335053,normal,1,worker,pipe.in,17
49.913040803,normal,0,worker,resource.serve,23
49.913040803,normal,1,worker,pipe.out,17
54.485089429,normal,1,worker,resource.serve,17
248.149993412,normal,2,worker,pipe.in,16
248.149993412,normal,2,worker,pipe.out,16
441.493859789,normal,2,worker,resource.serve,16
625.805024250,normal,3,worker,pipe.in,23
625.805024250,normal,3,worker,pipe.out,23
700.512949940,normal,4,worker,pipe.in,10
830.461026699,normal,3,worker,resource.serve,23
830.461026699,normal,4,worker,pipe.out,10
847.855816062,normal,4,worker,resource.serve,10
1127.160757415,normal,5,worker,pipe.in,23
1127.160757415,normal,5,worker,pipe.out,23
1166.027599075,normal,5,worker,resource.serve,23
1251.929283365,normal,6,worker,pipe.in,20
1251.929283365,normal,6,worker,pipe.out,20
1284.275103075,normal,7,worker,pipe.in,21
1347.512993521,normal,6,worker,resource.serve,20
1347.512993521,normal,7,worker,pipe.out,21
1541.899381582,normal,7,worker,resource.serve,21
1848.441225565,normal,8,worker,pipe.in,11
1848.441225565,normal,8,worker,pipe.out,11
1932.961092209,normal,8,worker,resource.serve,11
2240.943354699,normal,9,worker,pipe.in,22
2240.943354699,normal,9,worker,pipe.out,22
2265.566852517,normal,10,worker,pipe.in,30
2317.278253108,normal,9,worker,resource.serve,22
2317.278253108,normal,10,worker,pipe.out,30
2554.675714055,normal,11,worker,pipe.in,28
2618.740849180,normal,12,worker,pipe.in,12
2632.813111258,normal,13,worker,pipe.in,17
2910.792233711,normal,10,worker,resource.serve,30
2910.792233711,normal,11,worker,pipe.out,28
3077.745021529,normal,14,worker,pipe.in,17
3681.804460196,normal,15,worker,pipe.in,22
3779.512534186,normal,16,worker,pipe.in,30
4090.875545150,normal,11,worker,resource.serve,28
4090.875545150,normal,12,worker,pipe.out,12
4112.177708608,normal,12,worker,resource.serve,12
4112.177708608,normal,13,worker,pipe.out,17
4186.794914503,normal,13,worker,resource.serve,17
4186.794914503,normal,14,worker,pipe.out,17
4318.442414000,normal,17,worker,pipe.in,30
4340.666385782,normal,18,worker,pipe.in,30
4375.357825977,normal,14,worker,resource.serve,17
4375.357825977,normal,15,worker,pipe.out,22
4396.977101389,normal,19,worker,pipe.in,15
4583.091251682,normal,20,worker,pipe.in,18
4662.700806454,normal,15,worker,resource.serve,22
4662.700806454,normal,16,worker,pipe.out,30
4969.195980592,normal,16,worker,resource.serve,30
4969.195980592,normal,17,worker,pipe.out,30
5213.417601642,normal,17,worker,resource.serve,30
5213.417601642,normal,18,worker,pipe.out,30
5559.605238443,normal,18,worker,resource.serve,30
5559.605238443,normal,19,worker,pipe.out,15
5837.190248640,normal,19,worker,resource.serve,15
5837.190248640,normal,20,worker,pipe.out,18
5950.673162214,normal,21,worker,pipe.in,17
6106.489838444,normal,20,worker,resource.serve,18
6106.489838444,normal,21,worker,pipe.out,17
6384.438244483,normal,21,worker,resource.serve,17
6468.132158445,normal,22,worker,pipe.in,22
6468.132158445,normal,22,worker,pipe.out,22
6520.264945496,normal,22,worker,resource.serve,22
6561.618408373,normal,23,worker,pipe.in,28
6561.618408373,normal,23,worker,pipe.out,28
6667.420973560,normal,23,worker,resource.serve,28
7188.751262326,normal,24,worker,pipe.in,30
7188.751262326,normal,24,worker,pipe.out,30
7396.234526404,normal,25,worker,pipe.in,30
7580.453185706,normal,26,worker,pipe.in,18
7625.571122030,normal,27,worker,pipe.in,27
7836.772789002,normal,24,worker,resource.serve,30
7836.772789002,normal,25,worker,pipe.out,30
7857.863514232,normal,28,worker,pipe.in,23
8018.237158385,urgent,0,worker,pipe.in,4
8018.237158385,normal,25,worker,pipe.in,30
8018.237158385,normal,25,worker,resource.preempted,30
8018.237158385,urgent,0,worker,pipe.out,4
8255.201029505,urgent,0,worker,resource.serve,4
8255.201029505,normal,25,worker,pipe.out,30
8486.062775099,normal,25,worker,resource.serve,30
8486.062775099,normal,26,worker,pipe.out,18
8512.862063805,normal,26,worker,resource.serve,18
8512.862063805,normal,27,worker,pipe.out,27
8542.177775118,normal,29,worker,pipe.in,11
8696.532862972,normal,27,worker,resource.serve,27
8696.532862972,normal,28,worker,pipe.out,23
8734.682332207,normal,28,worker,resource.serve,23
8734.682332207,normal,29,worker,pipe.out,11
8753.858847901,normal,29,worker,resource.serve,11
9134.384368328,normal,30,worker,pipe.in,23
9134.384368328,normal,30,worker,pipe.out,23
9246.107955706,normal,30,worker,resource.serve,23
9406.590378189,normal,31,worker,pipe.in,29
9406.590378189,normal,31,worker,pipe.out,29
9625.000973941,normal,31,worker,resource.serve,29
9636.118275916,urgent,1,worker,pipe.in,5
9636.118275916,urgent,1,worker,pipe.out,5
9636.695647801,urgent,1,worker,resource.serve,5
11072.273154374,normal,32,worker,pipe.in,13
11072.273154374,normal,32,worker,pipe.out,13
11172.368493323,normal,32,worker,resource.serve,13
11415.711210823,normal,33,worker,pipe.in,18
11415.711210823,normal,33,worker,pipe.out,18
11490.551853380,normal,33,worker,resource.serve,18
11854.791807040,normal,34,worker,pipe.in,19
11854.791807040,normal,34,worker,pipe.out,19
11969.671582824,normal,34,worker,resource.serve,19
12025.946051615,normal,35,worker,pipe.in,18
12025.946051615,normal,35,worker,pipe.out,18
12284.304693889,normal,35,worker,resource.serve,18
13097.414730980,normal,36,worker,pipe.in,26
13097.414730980,normal,36,worker,pipe.out,26
13628.911360163,normal,36,worker,resource.serve,26
13828.688303491,normal,37,worker,pipe.in,19
13828.688303491,normal,37,worker,pipe.out,19
13963.320707091,normal,37,worker,resource.serve,19
14381.609213366,normal,38,worker,pipe.in,16
14381.609213366,normal,38,worker,pipe.out,16
14431.368664391,normal,39,worker,pipe.in,27
14611.630514253,normal,38,worker,resource.serve,16
14611.630514253,normal,39,worker,pipe.out,27
15301.919839754,normal,39,worker,resource.serve,27
15351.857926270,normal,40,worker,pipe.in,10
15351.857926270,normal,40,worker,pipe.out,10
15418.919364046,normal,40,worker,resource.serve,10
15625.954626627,normal,41,worker,pipe.in,13
15625.954626627,normal,41,worker,pipe.out,13
15900.211575902,normal,41,worker,resource.serve,13
16419.894225302,normal,42,worker,pipe.in,19
16419.894225302,normal,42,worker,pipe.out,19
16472.255249139,normal,42,worker,resource.serve,19
16502.009163586,normal,43,worker,pipe.in,28
16502.009163586,normal,43,worker,pipe.out,28
16527.081938335,normal,43,worker,resource.serve,28
16734.230083868,urgent,2,worker,pipe.in,4
16734.230083868,urgent,2,worker,pipe.out,4
16886.870413510,urgent,2,worker,resource.serve,4
17382.962150916,normal,44,worker,pipe.in,27
17382.962150916,normal,44,worker,pipe.out,27
17420.064169340,normal,44,worker,resource.serve,27
17818.480204946,normal,45,worker,pipe.in,25
17818.480204946,normal,45,worker,pipe.out,25
17863.599108038,normal,45,worker,resource.serve,25
18698.863905021,normal,46,worker,pipe.in,26
18698.863905021,normal,46,worker,pipe.out,26
18841.903452458,normal,46,worker,resource.serve,26
19316.598070304,normal,47,worker,pipe.in,16
19316.598070304,normal,47,worker,pipe.out,16
19541.810884695,normal,47,worker,resource.serve,16
20109.755390857,normal,48,worker,pipe.in,16
20109.755390857,normal,48,worker,pipe.out,16
20191.218996064,normal,48,worker,resource.serve,16
20484.183976048,normal,49,worker,pipe.in,30
20484.183976048,normal,49,worker,pipe.out,30
20624.427862433,normal,50,worker,pipe.in,24
20663.120408863,normal,51,worker,pipe.in,17
20682.970649833,normal,52,worker,pipe.in,10
20949.215107980,normal,53,worker,pipe.in,17
21173.803986105,normal,49,worker,resource.serve,30
21173.803986105,normal,50,worker,pipe.out,24
21175.536022348,normal,50,worker,resource.serve,24
21175.536022348,normal,51,worker,pipe.out,17
21215.555329820,normal,54,worker,pipe.in,11
21293.552750087,normal,55,worker,pipe.in,11
21384.713698988,normal,51,worker,resource.serve,17
21384.713698988,normal,52,worker,pipe.out,10
21392.062998951,normal,52,worker,resource.serve,10
21392.062998951,normal,53,worker,pipe.out,17
21438.271515829,normal,53,worker,resource.serve,17
21438.271515829,normal,54,worker,pipe.out,11
21559.884190617,normal,54,worker,resource.serve,11
21559.884190617,normal,55,worker,pipe.out,11
21586.405170112,normal,55,worker,resource.serve,11
21882.606337410,normal,56,worker,pipe.in,14
21882.606337410,normal,56,worker,pipe.out,14
22182.251464310,normal,56,worker,resource.serve,14
22268.109752762,normal,57,worker,pipe.in,28
22268.109752762,normal,57,worker,pipe.out,28
22460.088958772,normal,58,worker,pipe.in,23
22523.457126729,normal,59,worker,pipe.in,13
22698.007387668,normal,57,worker,resource.serve,28
22698.007387668,normal,58,worker,pipe.out,23
22798.613185133,normal,58,worker,resource.serve,23
22798.613185133,normal,59,worker,pipe.out,13
22828.835347781,urgent,3,worker,pipe.in,1
22828.835347781,normal,59,worker,pipe.in,13
22828.835347781,normal,59,worker,resource.preempted,13
22828.835347781,urgent,3,worker,pipe.out,1
22846.203791242,normal,60,worker,pipe.in,13
22864.962010388,normal,61,worker,pipe.in,20
22870.290807252,urgent,3,worker,resource.serve,1
22870.290807252,normal,59,worker,pipe.out,13
22908.904002618,normal,59,worker,resource.serve,13
22908.904002618,normal,60,worker,pipe.out,13
22923.946671982,normal,60,worker,resource.serve,13
22923.946671982,normal,61,worker,pipe.out,20
22966.483874513,normal,61,worker,resource.serve,20
23348.683469526,normal,62,worker,pipe.in,27
23348.683469526,normal,62,worker,pipe.out,27
23496.637166619,normal,62,worker,resource.serve,27
23527.279274699,normal,63,worker,pipe.in,18
23527.279274699,normal,63,worker,pipe.out,18
23713.598718948,normal,64,worker,pipe.in,12
23889.226158169,normal,65,worker,pipe.in,27
23900.840043944,normal,63,worker,resource.serve,18
23900.840043944,normal,64,worker,pipe.out,12
23920.138030907,normal,66,worker,pipe.in,27
24027.556353701,normal,64,worker,resource.serve,12
24027.556353701,normal,65,worker,pipe.out,27
24462.555151011,normal,67,worker,pipe.in,17
24517.123645165,normal,68,worker,pipe.in,25
24714.086313499,normal,69,worker,pipe.in,22
24965.441137940,normal,65,worker,resource.serve,27
24965.441137940,normal,66,worker,pipe.out,27
25014.011185055,normal,66,worker,resource.serve,27
25014.011185055,normal,67,worker,pipe.out,17
25014.377994824,normal,67,worker,resource.serve,17
25014.377994824,normal,68,worker,pipe.out,25
25138.124986531,normal,68,worker,resource.serve,25
25138.124986531,normal,69,worker,pipe.out,22
25412.281436852,normal,70,worker,pipe.in,24
25513.027847554,normal,71,worker,pipe.in,27
25712.482462920,normal,69,worker,resource.serve,22
25712.482462920,normal,70,worker,pipe.out,24
25838.326464180,normal,72,worker,pipe.in,16
25872.523850704,normal,70,worker,resource.serve,24
25872.523850704,normal,71,worker,pipe.out,27
25943.921322946,normal,73,worker,pipe.in,28
26343.164663794,normal,74,worker,pipe.in,11
26756.633427859,normal,75,worker,pipe.in,11
26772.066368153,normal,76,worker,pipe.in,25
26807.921685859,normal,71,worker,resource.serve,27
26807.921685859,normal,72,worker,pipe.out,16
26856.913340344,urgent,4,worker,pipe.in,2
26856.913340344,normal,72,worker,pipe.in,16
26856.913340344,normal,72,worker,resource.preempted,16
26856.913340344,urgent,4,worker,pipe.out,2
26871.091901142,urgent,4,worker,resource.serve,2
26871.091901142,normal,72,worker,pipe.out,16
26981.725645489,normal,77,worker,pipe.in,15
27003.020242686,normal,78,worker,pipe.in,12
27067.734039713,urgent,5,worker,pipe.in,2
27067.734039713,normal,72,worker,pipe.in,16
27067.734039713,normal,72,worker,resource.preempted,16
27067.734039713,urgent,5,worker,pipe.out,2
27124.541501249,urgent,5,worker,resource.serve,2
27124.541501249,normal,72,worker,pipe.out,16
27185.374749646,normal,72,worker,resource.serve,16
27185.374749646,normal,73,worker,pipe.out,28
27340.395539196,normal,79,worker,pipe.in,28
27421.475088222,normal,73,worker,resource.serve,28
27421.475088222,normal,74,worker,pipe.out,11
27527.730440170,normal,74,worker,resource.serve,11
27527.730440170,normal,75,worker,pipe.out,11
27587.503528787,normal,75,worker,resource.serve,11
27587.503528787,normal,76,worker,pipe.out,25
27611.200031467,normal,80,worker,pipe.in,26
27725.301496893,normal,81,worker,pipe.in,18
27793.846028968,normal,82,worker,pipe.in,20
27806.574169467,normal,76,worker,resource.serve,25
27806.574169467,normal,77,worker,pipe.out,15
27875.658827669,normal,83,worker,pipe.in,30
27882.148157306,normal,77,worker,resource.serve,15
27882.148157306,normal,78,worker,pipe.out,12
27927.754931762,normal,78,worker,resource.serve,12
27927.754931762,normal,79,worker,pipe.out,28
27982.660059338,normal,84,worker,pipe.in,12
27985.467794470,normal,85,worker,pipe.in,29
28318.013410298,normal,79,worker,resource.serve,28
28318.013410298,normal,80,worker,pipe.out,26