19
19
Attached health checks should query the '/health' path.
20
20
"""
21
21
22
+ from ctypes import c_bool
22
23
from flask import Flask , make_response , render_template
24
+ from multiprocessing import Process , Value
23
25
from random import random
24
26
from re import sub
25
27
from requests import get
26
28
from socket import gethostname
27
- from multiprocessing import Process
29
+ from time import sleep
28
30
29
31
PORT_NUMBER = 80
30
32
31
33
app = Flask (__name__ )
32
34
_is_healthy = True
33
- _worker = None
35
+ _cpu_burner = None
36
+
37
+
38
+ @app .before_first_request
39
+ def init ():
40
+ global _cpu_burner
41
+ _cpu_burner = CpuBurner ()
34
42
35
43
36
44
@app .route ('/' )
37
45
def index ():
38
46
"""Returns the demo UI."""
39
- global _is_healthy
47
+ global _cpu_burner , _is_healthy
40
48
return render_template ('index.html' ,
41
49
hostname = gethostname (),
42
50
zone = _get_zone (),
43
51
template = _get_template (),
44
52
healthy = _is_healthy ,
45
- working = _is_working ())
53
+ working = _cpu_burner . is_running ())
46
54
47
55
48
56
@app .route ('/health' )
@@ -60,15 +68,15 @@ def health():
60
68
@app .route ('/makeHealthy' )
61
69
def make_healthy ():
62
70
"""Sets the server to simulate a 'healthy' status."""
63
- global _is_healthy
71
+ global _cpu_burner , _is_healthy
64
72
_is_healthy = True
65
73
66
74
template = render_template ('index.html' ,
67
75
hostname = gethostname (),
68
76
zone = _get_zone (),
69
77
template = _get_template (),
70
78
healthy = True ,
71
- working = _is_working ())
79
+ working = _cpu_burner . is_running ())
72
80
response = make_response (template , 302 )
73
81
response .headers ['Location' ] = '/'
74
82
return response
@@ -77,15 +85,15 @@ def make_healthy():
77
85
@app .route ('/makeUnhealthy' )
78
86
def make_unhealthy ():
79
87
"""Sets the server to simulate an 'unhealthy' status."""
80
- global _is_healthy
88
+ global _cpu_burner , _is_healthy
81
89
_is_healthy = False
82
90
83
91
template = render_template ('index.html' ,
84
92
hostname = gethostname (),
85
93
zone = _get_zone (),
86
94
template = _get_template (),
87
95
healthy = False ,
88
- working = _is_working ())
96
+ working = _cpu_burner . is_running ())
89
97
response = make_response (template , 302 )
90
98
response .headers ['Location' ] = '/'
91
99
return response
@@ -94,10 +102,8 @@ def make_unhealthy():
94
102
@app .route ('/startLoad' )
95
103
def start_load ():
96
104
"""Sets the server to simulate high CPU load."""
97
- global _worker , _is_healthy
98
- if not _is_working ():
99
- _worker = Process (target = _burn_cpu )
100
- _worker .start ()
105
+ global _cpu_burner , _is_healthy
106
+ _cpu_burner .start ()
101
107
102
108
template = render_template ('index.html' ,
103
109
hostname = gethostname (),
@@ -113,10 +119,8 @@ def start_load():
113
119
@app .route ('/stopLoad' )
114
120
def stop_load ():
115
121
"""Sets the server to stop simulating CPU load."""
116
- global _worker , _is_healthy
117
- if _is_working ():
118
- _worker .terminate ()
119
- _worker = None
122
+ global _cpu_burner , _is_healthy
123
+ _cpu_burner .stop ()
120
124
121
125
template = render_template ('index.html' ,
122
126
hostname = gethostname (),
@@ -162,16 +166,32 @@ def _get_template():
162
166
return ''
163
167
164
168
165
- def _is_working ():
166
- """Returns TRUE if the server is currently simulating CPU load."""
167
- global _worker
168
- return _worker is not None and _worker .is_alive ()
169
-
170
-
171
- def _burn_cpu ():
172
- """Burn CPU cycles to simulate high CPU load."""
173
- while True :
174
- random ()* random ()
169
+ class CpuBurner :
170
+ """
171
+ Object to asynchronously burn CPU cycles to simulate high CPU load.
172
+ Burns CPU in a separate process and can be toggled on and off.
173
+ """
174
+ def __init__ (self ):
175
+ self ._toggle = Value (c_bool , False , lock = True )
176
+ self ._process = Process (target = self ._burn_cpu )
177
+ self ._process .start ()
178
+
179
+ def start (self ):
180
+ """Start burning CPU."""
181
+ self ._toggle .value = True
182
+
183
+ def stop (self ):
184
+ """Stop burning CPU."""
185
+ self ._toggle .value = False
186
+
187
+ def is_running (self ):
188
+ """Returns true if currently burning CPU."""
189
+ return self ._toggle .value
190
+
191
+ def _burn_cpu (self ):
192
+ """Burn CPU cycles if work is toggled, otherwise sleep."""
193
+ while True :
194
+ random ()* random () if self ._toggle .value else sleep (1 )
175
195
176
196
177
197
if __name__ == "__main__" :
0 commit comments