Chris Farr writes:
> Hi Dale,
>
> Thanks again. Will think more about your suggestions. I'm starting to think
> that SimPy cannot handle my simulation without some type of extension to
> its core capabilities. Which surprises me, as I thought my simulation was
> pretty basic. It could also be that I'm a newbie at SimPy I guess ...
What's wrong with a semaphore and a queue?
```
from collections import namedtuple
import random
import simpy
env = simpy.Environment()
# Resouce is a semaphore, has capacity
toolshed = simpy.Resource(env, capacity=3)
Job = namedtuple("Job", ["size"])
# Stores are queeus
job_queue = simpy.Store(env)
def job_producer(env, queue):
"""produces random size jobs and puts them in the queue"""
while True:
yield env.timeout(1)
job = Job(random.randint(100,500))
yield queue.put(job)
print(f"{env.now} : {job}")
def worker_process(env, work_rate=100, id=1):
"""consumes a job and a tool to do work"""
while True:
print(f"{env.now} : worker {id} waiting on job")
job = yield job_queue.get()
print(f"{env.now} : worker {id} got job")
print(f"{env.now} : worker {id} waiting for tool")
# set the event, then yield, so it can be released later
tool = toolshed.request()
yield tool
print(f"{env.now} : worker {id} got tool")
# do the work
yield env.timeout(job.size / work_rate)
print(f"{env.now} : worker {id} done")
# release the semaphore
toolshed.release(tool)
print(f"{env.now} : worker {id} releasing tool")
# spawn the processes
producer = env.process(job_producer(env, job_queue))
workers = [env.process(worker_process(env, 100, i)) for i in range(10)]
# run the sim
env.run(until=50)
```
Adding a maintenance cycle would be simple with an interrupt in
worker_process, with a try:except: that pauses until the cycle is
complete, then starts a new job timeout, either for the full job or the
remaining time.
Sample output follows:
```
0 : worker 0 waiting on job
0 : worker 1 waiting on job
0 : worker 2 waiting on job
0 : worker 3 waiting on job
0 : worker 4 waiting on job
0 : worker 5 waiting on job
0 : worker 6 waiting on job
0 : worker 7 waiting on job
0 : worker 8 waiting on job
0 : worker 9 waiting on job
1 : Job(size=364)
1 : worker 0 got job
1 : worker 0 waiting for tool
1 : worker 0 got tool
2 : Job(size=423)
2 : worker 1 got job
2 : worker 1 waiting for tool
2 : worker 1 got tool
3 : Job(size=190)
3 : worker 2 got job
3 : worker 2 waiting for tool
3 : worker 2 got tool
4 : Job(size=399)
4 : worker 3 got job
4 : worker 3 waiting for tool
4.640000000000001 : worker 0 done
4.640000000000001 : worker 0 releasing tool
4.640000000000001 : worker 0 waiting on job
4.640000000000001 : worker 3 got tool
4.9 : worker 2 done
4.9 : worker 2 releasing tool
4.9 : worker 2 waiting on job
5 : Job(size=217)
5 : worker 4 got job
5 : worker 4 waiting for tool
5 : worker 4 got tool
6 : Job(size=440)
6 : worker 5 got job
6 : worker 5 waiting for tool
6.23 : worker 1 done
6.23 : worker 1 releasing tool
6.23 : worker 1 waiting on job
6.23 : worker 5 got tool
7 : Job(size=231)
7 : worker 6 got job
7 : worker 6 waiting for tool
7.17 : worker 4 done
7.17 : worker 4 releasing tool
7.17 : worker 4 waiting on job
7.17 : worker 6 got tool
8 : Job(size=342)
8 : worker 7 got job
8 : worker 7 waiting for tool
8.63 : worker 3 done
8.63 : worker 3 releasing tool
8.63 : worker 3 waiting on job
8.63 : worker 7 got tool
9 : Job(size=385)
9 : worker 8 got job
9 : worker 8 waiting for tool
9.48 : worker 6 done
9.48 : worker 6 releasing tool
9.48 : worker 6 waiting on job
9.48 : worker 8 got tool
10 : Job(size=328)
10 : worker 9 got job
10 : worker 9 waiting for tool
10.63 : worker 5 done
10.63 : worker 5 releasing tool
10.63 : worker 5 waiting on job
10.63 : worker 9 got tool
11 : Job(size=181)
11 : worker 0 got job
11 : worker 0 waiting for tool
12 : Job(size=258)
12 : worker 2 got job
12 : worker 2 waiting for tool
12.05 : worker 7 done
12.05 : worker 7 releasing tool
12.05 : worker 7 waiting on job
12.05 : worker 0 got tool
13 : Job(size=494)
13 : worker 1 got job
13 : worker 1 waiting for tool
13.33 : worker 8 done
13.33 : worker 8 releasing tool
13.33 : worker 8 waiting on job
13.33 : worker 2 got tool
13.860000000000001 : worker 0 done
13.860000000000001 : worker 0 releasing tool
13.860000000000001 : worker 0 waiting on job
13.860000000000001 : worker 1 got tool
13.91 : worker 9 done
13.91 : worker 9 releasing tool
13.91 : worker 9 waiting on job
14 : Job(size=485)
14 : worker 4 got job
14 : worker 4 waiting for tool
14 : worker 4 got tool
15 : Job(size=264)
15 : worker 3 got job
15 : worker 3 waiting for tool
15.91 : worker 2 done
15.91 : worker 2 releasing tool
15.91 : worker 2 waiting on job
15.91 : worker 3 got tool
16 : Job(size=392)
16 : worker 6 got job
16 : worker 6 waiting for tool
17 : Job(size=204)
17 : worker 5 got job
17 : worker 5 waiting for tool
18 : Job(size=493)
18 : worker 7 got job
18 : worker 7 waiting for tool
18.55 : worker 3 done
18.55 : worker 3 releasing tool
18.55 : worker 3 waiting on job
18.55 : worker 6 got tool
18.8 : worker 1 done
18.8 : worker 1 releasing tool
18.8 : worker 1 waiting on job
18.8 : worker 5 got tool
18.85 : worker 4 done
18.85 : worker 4 releasing tool
18.85 : worker 4 waiting on job
18.85 : worker 7 got tool
19 : Job(size=283)
19 : worker 8 got job
19 : worker 8 waiting for tool
20 : Job(size=357)
20 : worker 0 got job
20 : worker 0 waiting for tool
20.84 : worker 5 done
20.84 : worker 5 releasing tool
20.84 : worker 5 waiting on job
20.84 : worker 8 got tool
21 : Job(size=191)
21 : worker 9 got job
21 : worker 9 waiting for tool
22 : Job(size=307)
22 : worker 2 got job
22 : worker 2 waiting for tool
22.47 : worker 6 done
22.47 : worker 6 releasing tool
22.47 : worker 6 waiting on job
22.47 : worker 0 got tool
23 : Job(size=429)
23 : worker 3 got job
23 : worker 3 waiting for tool
23.67 : worker 8 done
23.67 : worker 8 releasing tool
23.67 : worker 8 waiting on job
23.67 : worker 9 got tool
23.78 : worker 7 done
23.78 : worker 7 releasing tool
23.78 : worker 7 waiting on job
23.78 : worker 2 got tool
24 : Job(size=347)
24 : worker 1 got job
24 : worker 1 waiting for tool
25 : Job(size=319)
25 : worker 4 got job
25 : worker 4 waiting for tool
25.580000000000002 : worker 9 done
25.580000000000002 : worker 9 releasing tool
25.580000000000002 : worker 9 waiting on job
25.580000000000002 : worker 3 got tool
26 : Job(size=161)
26 : worker 5 got job
26 : worker 5 waiting for tool
26.04 : worker 0 done
26.04 : worker 0 releasing tool
26.04 : worker 0 waiting on job
26.04 : worker 1 got tool
26.85 : worker 2 done
26.85 : worker 2 releasing tool
26.85 : worker 2 waiting on job
26.85 : worker 4 got tool
27 : Job(size=107)
27 : worker 6 got job
27 : worker 6 waiting for tool
28 : Job(size=407)
28 : worker 8 got job
28 : worker 8 waiting for tool
29 : Job(size=216)
29 : worker 7 got job
29 : worker 7 waiting for tool
29.509999999999998 : worker 1 done
29.509999999999998 : worker 1 releasing tool
29.509999999999998 : worker 1 waiting on job
29.509999999999998 : worker 5 got tool
29.87 : worker 3 done
29.87 : worker 3 releasing tool
29.87 : worker 3 waiting on job
29.87 : worker 6 got tool
30 : Job(size=182)
30 : worker 9 got job
30 : worker 9 waiting for tool
30.040000000000003 : worker 4 done
30.040000000000003 : worker 4 releasing tool
30.040000000000003 : worker 4 waiting on job
30.040000000000003 : worker 8 got tool
30.94 : worker 6 done
30.94 : worker 6 releasing tool
30.94 : worker 6 waiting on job
30.94 : worker 7 got tool
31 : Job(size=335)
31 : worker 0 got job
31 : worker 0 waiting for tool
31.119999999999997 : worker 5 done
31.119999999999997 : worker 5 releasing tool
31.119999999999997 : worker 5 waiting on job
31.119999999999997 : worker 9 got tool
32 : Job(size=229)
32 : worker 2 got job
32 : worker 2 waiting for tool
32.94 : worker 9 done
32.94 : worker 9 releasing tool
32.94 : worker 9 waiting on job
32.94 : worker 0 got tool
33 : Job(size=421)
33 : worker 1 got job
33 : worker 1 waiting for tool
33.1 : worker 7 done
33.1 : worker 7 releasing tool
33.1 : worker 7 waiting on job
33.1 : worker 2 got tool
34 : Job(size=392)
34 : worker 3 got job
34 : worker 3 waiting for tool
34.11 : worker 8 done
34.11 : worker 8 releasing tool
34.11 : worker 8 waiting on job
34.11 : worker 1 got tool
35 : Job(size=303)
35 : worker 4 got job
35 : worker 4 waiting for tool
35.39 : worker 2 done
35.39 : worker 2 releasing tool
35.39 : worker 2 waiting on job
35.39 : worker 3 got tool
36 : Job(size=232)
36 : worker 6 got job
36 : worker 6 waiting for tool
36.29 : worker 0 done
36.29 : worker 0 releasing tool
36.29 : worker 0 waiting on job
36.29 : worker 4 got tool
37 : Job(size=253)
37 : worker 5 got job
37 : worker 5 waiting for tool
38 : Job(size=151)
38 : worker 9 got job
38 : worker 9 waiting for tool
38.32 : worker 1 done
38.32 : worker 1 releasing tool
38.32 : worker 1 waiting on job
38.32 : worker 6 got tool
39 : Job(size=226)
39 : worker 7 got job
39 : worker 7 waiting for tool
39.31 : worker 3 done
39.31 : worker 3 releasing tool
39.31 : worker 3 waiting on job
39.31 : worker 5 got tool
39.32 : worker 4 done
39.32 : worker 4 releasing tool
39.32 : worker 4 waiting on job
39.32 : worker 9 got tool
40 : Job(size=339)
40 : worker 8 got job
40 : worker 8 waiting for tool
40.64 : worker 6 done
40.64 : worker 6 releasing tool
40.64 : worker 6 waiting on job
40.64 : worker 7 got tool
40.83 : worker 9 done
40.83 : worker 9 releasing tool
40.83 : worker 9 waiting on job
40.83 : worker 8 got tool
41 : Job(size=359)
41 : worker 2 got job
41 : worker 2 waiting for tool
41.84 : worker 5 done
41.84 : worker 5 releasing tool
41.84 : worker 5 waiting on job
41.84 : worker 2 got tool
42 : Job(size=313)
42 : worker 0 got job
42 : worker 0 waiting for tool
42.9 : worker 7 done
42.9 : worker 7 releasing tool
42.9 : worker 7 waiting on job
42.9 : worker 0 got tool
43 : Job(size=205)
43 : worker 1 got job
43 : worker 1 waiting for tool
44 : Job(size=146)
44 : worker 3 got job
44 : worker 3 waiting for tool
44.22 : worker 8 done
44.22 : worker 8 releasing tool
44.22 : worker 8 waiting on job
44.22 : worker 1 got tool
45 : Job(size=260)
45 : worker 4 got job
45 : worker 4 waiting for tool
45.43000000000001 : worker 2 done
45.43000000000001 : worker 2 releasing tool
45.43000000000001 : worker 2 waiting on job
45.43000000000001 : worker 3 got tool
46 : Job(size=212)
46 : worker 6 got job
46 : worker 6 waiting for tool
46.03 : worker 0 done
46.03 : worker 0 releasing tool
46.03 : worker 0 waiting on job
46.03 : worker 4 got tool
46.269999999999996 : worker 1 done
46.269999999999996 : worker 1 releasing tool
46.269999999999996 : worker 1 waiting on job
46.269999999999996 : worker 6 got tool
46.89000000000001 : worker 3 done
46.89000000000001 : worker 3 releasing tool
46.89000000000001 : worker 3 waiting on job
47 : Job(size=294)
47 : worker 9 got job
47 : worker 9 waiting for tool
47 : worker 9 got tool
48 : Job(size=199)
48 : worker 5 got job
48 : worker 5 waiting for tool
48.38999999999999 : worker 6 done
48.38999999999999 : worker 6 releasing tool
48.38999999999999 : worker 6 waiting on job
48.38999999999999 : worker 5 got tool
48.63 : worker 4 done
48.63 : worker 4 releasing tool
48.63 : worker 4 waiting on job
49 : Job(size=212)
49 : worker 7 got job
49 : worker 7 waiting for tool
49 : worker 7 got tool
49.94 : worker 9 done
49.94 : worker 9 releasing tool
49.94 : worker 9 waiting on job
>>>
```
-- C