Skip to content

Commit e419ef3

Browse files
committed
Upgrading to websockets 14.2+.
1 parent 3bf3625 commit e419ef3

7 files changed

Lines changed: 35 additions & 21 deletions

File tree

README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Monitor
1717
:target: https://github.com/ReCodEx/wiki/wiki/Changelog
1818

1919
Monitor is an optional part of the ReCodEx solution for reporting progress of
20-
job evaluation back to users in the real time. It is a daemon that reads status messages of all running job evaluations from one ZeroMQ socket and send them to proper WebSocket connection. Monitor is written in Python, tested versions are 3.4 and 3.5.
20+
job evaluation back to users in the real time. It is a daemon that reads status messages of all running job evaluations from one ZeroMQ socket and send them to proper WebSocket connection. Monitor is written in Python (>= 3.9).
2121

2222
There is just one monitor instance required per broker. Also, monitor has to be
2323
publicly visible (has to have public IP address or be behind public proxy
@@ -64,7 +64,7 @@ Installation will provide you following files:
6464
- `/etc/recodex/monitor/config.yml` -- configuration file
6565
- `/etc/systemd/system/recodex-monitor.service` -- systemd startup script
6666
- code files will be installed in location depending on your system settings,
67-
mostly into `/usr/lib/python3.5/site-packages/monitor/` or similar
67+
mostly into `/usr/lib/python3.9/site-packages/monitor/` or similar
6868

6969
Systemd script runs monitor binary as specific _recodex_ user, so in `postinst`
7070
script user and group of this name are created. Also, ownership of configuration

monitor/test/test_ConfigManager.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ def test_websock_uri_default(self):
1818

1919
def test_websock_uri_loaded(self):
2020
handle, path = tempfile.mkstemp()
21+
os.close(handle)
2122
with open(path, 'w') as f:
2223
f.write('websocket_uri:\n - 77.75.76.3\n - 8080')
2324

@@ -35,6 +36,7 @@ def test_zeromq_uri_default(self):
3536

3637
def test_zeromq_uri_loaded(self):
3738
handle, path = tempfile.mkstemp()
39+
os.close(handle)
3840
with open(path, 'w') as f:
3941
f.write('zeromq_uri:\n - 77.75.76.3\n - 8080')
4042

@@ -52,6 +54,7 @@ def test_logger_path_default(self):
5254

5355
def test_logger_path_loaded(self):
5456
handle, path = tempfile.mkstemp()
57+
os.close(handle)
5558
with open(path, 'w') as f:
5659
f.write('logger:\n file: /var/log/tmp/file.log\n level: "debug"\n max-size: 564\n rotations: 7')
5760

@@ -78,6 +81,7 @@ def test_invalid_path(self):
7881

7982
def test_valid_creation(self):
8083
handle, path = tempfile.mkstemp()
84+
os.close(handle)
8185
logger = init_logger(path, logging.WARNING, 450, 2)
8286
logger.debug("aaa")
8387
logger.warning("bbb")
@@ -90,4 +94,8 @@ def test_valid_creation(self):
9094
# expect 5 lines - 3 of header and one with 'bbb' and one 'ccc'
9195
self.assertEqual(len(content), 5)
9296

97+
for handler in list(logger.handlers):
98+
handler.close()
99+
logger.removeHandler(handler)
100+
93101
os.remove(path)

monitor/test/test_websock_server.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
class TestWebsocketServer(unittest.TestCase):
1010
@patch('asyncio.set_event_loop')
11-
@patch('websockets.serve')
11+
@patch('monitor.websocket_connections.serve')
1212
def test_init(self, mock_websock_serve, mock_set_loop):
1313
loop = MagicMock()
1414
logger = MagicMock()
@@ -22,7 +22,8 @@ def test_init(self, mock_websock_serve, mock_set_loop):
2222
mock_websock_serve.assert_called_once_with(server.connection_handler, "ip_address", 4512)
2323
loop.run_until_complete.assert_called_once_with("0101")
2424

25-
def test_connection_handler(self):
25+
@patch('monitor.websocket_connections.serve')
26+
def test_connection_handler(self, mock_websock_serve):
2627
queue = asyncio.Queue()
2728
logger = MagicMock()
2829
connection_mock = MagicMock()
@@ -31,20 +32,22 @@ def test_connection_handler(self):
3132

3233
websocket_mock = MagicMock()
3334

34-
received_id = asyncio.Future()
35+
loop = asyncio.new_event_loop()
36+
received_id = loop.create_future()
3537
received_id.set_result("1234")
36-
response = asyncio.Future()
38+
response = loop.create_future()
3739
response.set_result(None)
3840
websocket_mock.recv.return_value = received_id
3941
websocket_mock.send.return_value = response
40-
41-
loop = asyncio.new_event_loop()
4242
queue.put_nowait("result text")
4343
queue.put_nowait(None)
4444

45+
start_server_future = loop.create_future()
46+
start_server_future.set_result("0101")
47+
mock_websock_serve.return_value = start_server_future
4548
websock_server = WebsocketServer(("localhost", 11111), connection_mock, loop, logger)
4649
# actually call the method
47-
loop.run_until_complete(websock_server.connection_handler(websocket_mock, None))
50+
loop.run_until_complete(websock_server.connection_handler(websocket_mock))
4851

4952
# test the constraints
5053
websocket_mock.recv.assert_called_once_with()
@@ -53,9 +56,11 @@ def test_connection_handler(self):
5356
connection_mock.remove_client.assert_called_once_with("1234", queue)
5457

5558
@patch('asyncio.set_event_loop')
56-
def test_run(self, mock_set_loop):
59+
@patch('monitor.websocket_connections.serve')
60+
def test_run(self, mock_websock_serve, mock_set_loop):
5761
loop = MagicMock()
5862
logger = MagicMock()
63+
mock_websock_serve.return_value = "0101"
5964
server = WebsocketServer(("ip_address", 123), None, loop, logger)
6065
server.run()
6166
mock_set_loop.assert_called_with(loop)

monitor/websocket_connections.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
"""
55

66
import asyncio
7-
import websockets
87
import threading
98

9+
from websockets.asyncio.server import serve
10+
from websockets.exceptions import ConnectionClosed
11+
1012

1113
class ClientConnections:
1214
"""
@@ -147,16 +149,15 @@ def __init__(self, websock_uri, connections, loop, logger):
147149
self._logger = logger
148150
hostname, port = websock_uri
149151
asyncio.set_event_loop(loop)
150-
start_server = websockets.serve(self.connection_handler, hostname, port)
151-
loop.run_until_complete(start_server)
152+
start_server = serve(self.connection_handler, hostname, port)
153+
self._server = loop.run_until_complete(start_server)
152154
self._logger.info("websocket server initialized at {}:{}".format(hostname, port))
153155

154-
async def connection_handler(self, websocket, path):
156+
async def connection_handler(self, websocket):
155157
"""
156158
Internal asyncio.coroutine function for handling one websocket request.
157159
158160
:param websocket: Socket with request
159-
:param path: Requested path of socket (not used)
160161
:return: Returns when socket is closed or poison pill is found in message queue
161162
from ClientConnections.
162163
"""
@@ -175,7 +176,7 @@ async def connection_handler(self, websocket, path):
175176
# send message to client
176177
await websocket.send(result)
177178
self._logger.debug("websocket server: message sent to channel '{}'".format(wanted_id))
178-
except websockets.ConnectionClosed:
179+
except ConnectionClosed:
179180
if wanted_id:
180181
self._logger.info("websocket server: connection closed for channel '{}'". format(wanted_id))
181182
finally:

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ classifiers = [
2525
]
2626
dependencies = [
2727
"pyzmq",
28-
"websockets==12.0",
28+
"websockets>=14.2",
2929
"PyYAML",
3030
]
3131
requires-python = ">=3.9"

recodex-monitor.spec

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
%define name recodex-monitor
22
%define short_name monitor
33
%define version 1.2.0
4-
%define unmangled_version 0086f2b6faa213766bc50f2746ee1bf0bdae77c1
5-
%define release 3
4+
%define unmangled_version 3bf3625a97b4970ef2c8b64889e7b32c9ac27e53
5+
%define release 4
66

77
Summary: Publish ZeroMQ messages through WebSockets
88
Name: %{name}
@@ -26,7 +26,7 @@ Requires(preun): systemd
2626
Requires(postun): systemd
2727
# %{?fedora:Requires: python3-PyYAML python3-websockets python3-zmq}
2828
# %{?rhel:Requires: python3-PyYAML python3-websockets python3-pyzmq}
29-
Requires: python3-PyYAML python3-websockets <= 12.0 python3-pyzmq
29+
Requires: python3-PyYAML python3-websockets >= 14.2 python3-pyzmq
3030

3131
Source0: https://github.com/ReCodEx/%{short_name}/archive/%{unmangled_version}.tar.gz#/%{short_name}-%{unmangled_version}.tar.gz
3232

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
pyzmq
77

88
# WebSockets
9-
websockets==12.0
9+
websockets>=14.2
1010

1111
# Configuration parsing
1212
PyYAML

0 commit comments

Comments
 (0)