-
Notifications
You must be signed in to change notification settings - Fork 3
/
resource.py
54 lines (45 loc) · 1.71 KB
/
resource.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import simpy
from functools import partial, wraps
class MonitoredResource(simpy.Resource):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.data = []
def request(self, *args, **kwargs):
self.data.append(('req',self._env.now))
return super().request(*args, **kwargs)
def release(self, *args, **kwargs):
self.data.append(('res',self._env.now))
return super().release(*args, **kwargs)
def patch_resource(resource, pre=None, post=None):
"""Patch *resource* so that it calls the callable *pre* before each
put/get/request/release operation and the callable *post* after each
operation. The only argument to these functions is the resource
instance.
"""
def get_wrapper(func):
# Generate a wrapper for put/get/request/release
@wraps(func)
def wrapper(*args, **kwargs):
# This is the actual wrapper
# Call "pre" callback
if pre:
pre(resource)
# Perform actual operation
ret = func(*args, **kwargs)
# Call "post" callback
if post:
post(resource)
return ret
return wrapper
# Replace the original operations with our wrapper
for name in ['put', 'get', 'request', 'release']:
if hasattr(resource, name):
setattr(resource, name, get_wrapper(getattr(resource, name)))
def monitor(data, resource):
"""This is our monitoring callback."""
item = (
resource._env.now, # The current simulation time
resource.count, # The number of users
len(resource.queue), # The number of queued processes
)
data.append(item)