Skip to content

Commit 34005ae

Browse files
tslatonkrinsman
authored andcommitted
Thread cpu_percent two different ways
1 parent 1c42939 commit 34005ae

File tree

1 file changed

+41
-2
lines changed

1 file changed

+41
-2
lines changed

nbresuse/__init__.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,53 @@
66
from notebook.utils import url_path_join
77
from notebook.base.handlers import IPythonHandler
88
from tornado import web
9+
910
try:
1011
# Traitlets >= 4.3.3
1112
from traitlets import Callable
1213
except ImportError:
1314
from .callable import Callable
1415

16+
from threading import Thread
17+
from concurrent.futures import ThreadPoolExecutor, as_completed
1518

1619
class MetricsHandler(IPythonHandler):
20+
def initialize(self):
21+
super().initialize()
22+
self.cpu_percent = 0
23+
# A better approach would use cpu_affinity to account for the
24+
# fact that the number of logical CPUs in the system is not
25+
# necessarily the same as the number of CPUs the process
26+
# can actually use. But cpu_affinity isn't available for OS X.
27+
self.cpu_count = psutil.cpu_count()
28+
29+
def update_cpu_percent():
30+
def get_cpu_percent(p):
31+
try:
32+
return p.cpu_percent(interval=0.1)
33+
# Avoid littering logs with stack traces complaining
34+
# about dead processes having no CPU usage
35+
except:
36+
return 0
37+
# This loop should execute roughly every "interval" seconds
38+
# Slower if max_workers is much less than the number of processes
39+
while True:
40+
cur_process = psutil.Process()
41+
all_processes = [cur_process] + cur_process.children(recursive=True)
42+
# Could have a worker for every process
43+
with ThreadPoolExecutor(max_workers=10) as executor:
44+
cpu_percents = [executor.submit(get_cpu_percent, p) for p in all_processes]
45+
total_percent = 0
46+
for future in as_completed(cpu_percents):
47+
try:
48+
total_percent += future.result()
49+
except:
50+
pass
51+
self.cpu_percent = total_percent
52+
53+
t = Thread(target=update_cpu_percent)
54+
t.start()
55+
1756
@web.authenticated
1857
def get(self):
1958
"""
@@ -61,8 +100,8 @@ def get_cpu_percent(p):
61100

62101
metrics = {
63102
'rss': rss,
64-
'cpu_percent': cpu_percent,
65-
'cpu_count': cpu_count,
103+
'cpu_percent': self.cpu_percent,
104+
'cpu_count': self.cpu_count,
66105
'limits': limits,
67106
}
68107
self.write(json.dumps(metrics))

0 commit comments

Comments
 (0)