Skip to content

Commit 9399b90

Browse files
author
Joel Collins
committed
Tidied up server management
1 parent 7ffb305 commit 9399b90

File tree

1 file changed

+98
-45
lines changed

1 file changed

+98
-45
lines changed

labthings/server/wsgi/gevent.py

Lines changed: 98 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -13,34 +13,34 @@
1313

1414

1515
class Server:
16-
def __init__(self, app):
16+
def __init__(
17+
self, app, host="0.0.0.0", port=5000, log=None, debug=False, zeroconf=True
18+
):
1719
self.app = app
1820
# Find LabThing attached to app
1921
self.labthing = current_labthing(app)
2022

21-
def run(
22-
self,
23-
host="0.0.0.0",
24-
port=5000,
25-
log=None,
26-
debug=False,
27-
stop_timeout=1,
28-
zeroconf=True,
29-
):
30-
# Type checks
31-
port = int(port)
32-
host = str(host)
23+
# Server properties
24+
self.host = host
25+
self.port = port
26+
self.log = log
27+
self.debug = debug
28+
self.zeroconf = zeroconf
3329

34-
# Unmodified version of app
35-
app_to_run = self.app
30+
# Servers
31+
self.wsgi_server = None
32+
self.zeroconf_server = None
33+
self.service_info = None
3634

37-
# Handle zeroconf
38-
zeroconf_server = None
39-
if zeroconf and self.labthing:
40-
service_info = ServiceInfo(
35+
# Events
36+
self.started_event = gevent.event.Event()
37+
38+
def register_zeroconf(self):
39+
if self.labthing:
40+
self.service_info = ServiceInfo(
4141
"_labthings._tcp.local.",
42-
f"{self.labthing.title}._labthings._tcp.local.",
43-
port=port,
42+
f"{self.labthing.safe_title}._labthings._tcp.local.",
43+
port=self.port,
4444
properties={
4545
"path": self.labthing.url_prefix,
4646
"title": self.labthing.title,
@@ -55,43 +55,96 @@ def run(
5555
]
5656
),
5757
)
58-
zeroconf_server = Zeroconf(ip_version=IPVersion.V4Only)
59-
zeroconf_server.register_service(service_info)
58+
self.zeroconf_server = Zeroconf(ip_version=IPVersion.V4Only)
59+
self.zeroconf_server.register_service(self.service_info)
60+
61+
def stop(self, timeout=1):
62+
# Unregister zeroconf service
63+
if self.zeroconf_server:
64+
self.zeroconf_server.unregister_service(self.service_info)
65+
self.zeroconf_server.close()
66+
self.zeroconf_server = None
67+
# Stop WSGI server with timeout
68+
if self.wsgi_server:
69+
self.wsgi_server.stop(timeout=timeout)
70+
self.wsgi_server = None
71+
# Clear started event
72+
if self.started_event.is_set():
73+
self.started_event.clear()
74+
75+
def start(self):
76+
# Unmodified version of app
77+
app_to_run = self.app
78+
79+
# Handle zeroconf
80+
if self.zeroconf:
81+
self.register_zeroconf()
6082

6183
# Handle logging
62-
if not log:
63-
log = logging.getLogger()
84+
if not self.log:
85+
self.log = logging.getLogger()
6486

6587
# Handle debug mode
66-
if debug:
67-
log.setLevel(logging.DEBUG)
88+
if self.debug:
89+
self.log.setLevel(logging.DEBUG)
6890
app_to_run = DebuggedApplication(self.app)
6991
logging.getLogger("zeroconf").setLevel(logging.DEBUG)
7092

7193
# Slightly more useful logger output
72-
friendlyhost = "localhost" if host == "0.0.0.0" else host
94+
friendlyhost = "localhost" if self.host == "0.0.0.0" else self.host
7395
print("Starting LabThings WSGI Server")
74-
print(f"Debug mode: {debug}")
75-
print(f"Running on http://{friendlyhost}:{port} (Press CTRL+C to quit)")
96+
print(f"Debug mode: {self.debug}")
97+
print(f"Running on http://{friendlyhost}:{self.port} (Press CTRL+C to quit)")
7698

7799
# Create WSGIServer
78-
wsgi_server = gevent.pywsgi.WSGIServer(
79-
(host, port), app_to_run, handler_class=WebSocketHandler, log=log
100+
self.wsgi_server = gevent.pywsgi.WSGIServer(
101+
(self.host, self.port),
102+
app_to_run,
103+
handler_class=WebSocketHandler,
104+
log=self.log,
80105
)
81106

82-
def stop():
83-
# Unregister zeroconf service
84-
if zeroconf_server:
85-
zeroconf_server.unregister_service(service_info)
86-
zeroconf_server.close()
87-
# Stop WSGI server with timeout
88-
wsgi_server.stop(timeout=stop_timeout)
89-
90107
# Serve
91-
signal.signal(signal.SIGTERM, stop)
108+
signal.signal(signal.SIGTERM, self.stop)
92109

110+
# Set started event
111+
self.started_event.set()
93112
try:
94-
wsgi_server.serve_forever()
95-
except (KeyboardInterrupt, SystemExit):
96-
logging.warning("Terminating by KeyboardInterrupt or SystemExit")
97-
stop()
113+
self.wsgi_server.serve_forever()
114+
# Ignore the exit lines in coverage
115+
# as I can't find a way to test a KeyboardInterrupt...
116+
except (KeyboardInterrupt, SystemExit): # pragma: no cover
117+
logging.warning(
118+
"Terminating by KeyboardInterrupt or SystemExit"
119+
) # pragma: no cover
120+
self.stop() # pragma: no cover
121+
122+
def run(
123+
self, host=None, port=None, log=None, debug=None, zeroconf=None,
124+
):
125+
"""Starts the server allowing for runtime parameters. Designed to immitate
126+
the old Flask app.run style of starting an app
127+
128+
Args:
129+
host (string, optional): Host IP address. Defaults to None.
130+
port (int, optional): Host port. Defaults to None.
131+
log (optional): Logger to log to. Defaults to None.
132+
debug (bool, optional): Enable server debug mode. Defaults to None.
133+
zeroconf (bool, optional): Enable the zeroconf server. Defaults to None.
134+
"""
135+
if port is not None:
136+
self.port = int(port)
137+
138+
if host is not None:
139+
self.host = str(host)
140+
141+
if log is not None:
142+
self.log = log
143+
144+
if debug is not None:
145+
self.debug = debug
146+
147+
if zeroconf is not None:
148+
self.zeroconf = zeroconf
149+
150+
self.start()

0 commit comments

Comments
 (0)