Skip to content

Commit cddda58

Browse files
authored
Merge pull request #36 from scivisum/bug/RD-41645_optimise_performance
[RD-41645] Use a threading Event to speed up message polling
2 parents 34718eb + f4e0cff commit cddda58

File tree

4 files changed

+51
-14
lines changed

4 files changed

+51
-14
lines changed

browserdebuggertools/chrome/interface.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def set_timeout(self, value):
9090
self._session_manager.timeout = _timeout
9191

9292
def navigate(self, url):
93-
""" Navigates to the given url asynchronously
93+
""" Navigates to the given url
9494
"""
9595
return self.execute("Page", "navigate", {
9696
"url": url

browserdebuggertools/wssessionmanager.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import socket
55
import time
66
import collections
7-
from threading import Thread, Lock
7+
from threading import Thread, Lock, Event
88

99
from typing import Dict
1010

@@ -28,7 +28,7 @@ class _WSMessageProducer(Thread):
2828
"""
2929
_CONN_TIMEOUT = 15
3030
_BLOCKED_TIMEOUT = 5
31-
_POLL_INTERVAL = 0.01 # How long to wait for new ws messages
31+
_POLL_INTERVAL = 1 # How long to wait for new ws messages
3232

3333
def __init__(self, port, send_queue, on_message):
3434
super(_WSMessageProducer, self).__init__()
@@ -41,6 +41,7 @@ def __init__(self, port, send_queue, on_message):
4141
self.exception = None
4242
self.ws = self._get_websocket()
4343
self.daemon = True
44+
self.poll_signal = Event()
4445

4546
def __del__(self):
4647
self.close()
@@ -122,8 +123,9 @@ def run(self):
122123
self._last_ws_attempt = time.time()
123124
self._empty_send_queue()
124125
self._empty_websocket()
125-
126-
time.sleep(self._POLL_INTERVAL)
126+
self.poll_signal.wait(self._POLL_INTERVAL)
127+
if self.poll_signal.isSet():
128+
self.poll_signal.clear()
127129

128130
@property
129131
def blocked(self):
@@ -386,6 +388,7 @@ def _wait_for_result(self, result_id):
386388
return self._results.pop(result_id)
387389

388390
self._check_message_producer()
391+
self._message_producer.poll_signal.set()
389392
time.sleep(0.01)
390393
raise DevToolsTimeoutException(
391394
"Reached timeout limit of {}, waiting for a response message".format(self.timeout)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
setup(
1414
name="browserdebuggertools",
15-
version="6.0.1",
15+
version="6.0.2",
1616
python_requires='>=3.8',
1717
packages=PACKAGES,
1818
install_requires=requires,

tests/unittests/test_wssessionmanager.py

Lines changed: 42 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import collections
22
import copy
33
import socket
4+
import time
45
from unittest import TestCase
56

67
from mock import patch, MagicMock, call, PropertyMock
@@ -173,13 +174,11 @@ def test_fail(self):
173174
], self.processed_messages)
174175

175176

176-
@patch(MODULE_PATH + "time")
177177
@patch(MODULE_PATH + "_WSMessageProducer._empty_send_queue", MagicMock())
178178
@patch(MODULE_PATH + "_WSMessageProducer._empty_websocket", MagicMock())
179179
class Test__WSMessageProducer_run(WSMessageProducerTest):
180180

181-
def prepare(self, time):
182-
_WSMessageProducer._POLL_INTERVAL = 0
181+
def prepare(self, time_):
183182
self.next_time = 0
184183

185184
def increment_time():
@@ -190,25 +189,60 @@ def increment_time():
190189

191190
return current_time
192191

193-
time.time = increment_time
192+
time_.time = increment_time
194193

195-
def test(self, time):
196-
self.prepare(time)
194+
@patch(MODULE_PATH + "_WSMessageProducer._POLL_INTERVAL", 0)
195+
@patch(MODULE_PATH + "time")
196+
def test(self, time_):
197+
self.prepare(time_)
197198

198199
self.ws_message_producer.run()
199200

200201
self.assertEqual(10, self.ws_message_producer._last_ws_attempt)
201202

202-
def test_exception(self, time):
203+
@patch(MODULE_PATH + "_WSMessageProducer._POLL_INTERVAL", 0)
204+
@patch(MODULE_PATH + "time")
205+
def test_exception(self, time_):
203206
exception = Exception()
204207
self.ws_message_producer._empty_send_queue.side_effect = exception
205-
self.prepare(time)
208+
self.prepare(time_)
206209

207210
self.ws_message_producer.run()
208211

209212
self.assertEqual(0, self.ws_message_producer._last_ws_attempt)
210213
self.assertEqual(exception, self.ws_message_producer.exception)
211214

215+
def test_wait_timeout(self):
216+
217+
def _stop():
218+
self.ws_message_producer._continue = False
219+
220+
self.ws_message_producer._empty_send_queue = MagicMock()
221+
self.ws_message_producer._empty_websocket.side_effect = _stop
222+
self.ws_message_producer.poll_signal.clear = MagicMock()
223+
start = time.time()
224+
225+
self.ws_message_producer.run()
226+
227+
self.assertGreater(time.time() - start, 1)
228+
self.ws_message_producer.poll_signal.clear.assert_not_called()
229+
230+
def test_poll_signal_set(self):
231+
232+
def _stop():
233+
self.ws_message_producer._continue = False
234+
235+
self.ws_message_producer._empty_send_queue = MagicMock()
236+
self.ws_message_producer._empty_websocket.side_effect = _stop
237+
self.ws_message_producer.poll_signal.set()
238+
self.ws_message_producer.poll_signal.clear = MagicMock()
239+
240+
start = time.time()
241+
self.ws_message_producer.run()
242+
243+
self.assertLess(time.time() - start, 1)
244+
self.ws_message_producer.poll_signal.clear.assert_called_once_with()
245+
212246

213247
class Test__WSMessagingThread_blocked(WSMessageProducerTest):
214248

0 commit comments

Comments
 (0)