fix read timeouts in base.py, use seconds everywhere
This commit is contained in:
parent
ed5ce48f65
commit
ad67e6eaee
|
@ -35,11 +35,14 @@ _LONG_MESSAGE_SIZE = 20
|
||||||
_MEDIUM_MESSAGE_SIZE = 15
|
_MEDIUM_MESSAGE_SIZE = 15
|
||||||
_MAX_READ_SIZE = 32
|
_MAX_READ_SIZE = 32
|
||||||
|
|
||||||
"""Default timeout on read (in ms)."""
|
"""Default timeout on read (in seconds)."""
|
||||||
DEFAULT_TIMEOUT = 3000
|
DEFAULT_TIMEOUT = 2
|
||||||
_RECEIVER_REQUEST_TIMEOUT = 500
|
# the receiver itself should reply very fast, within 500ms
|
||||||
|
_RECEIVER_REQUEST_TIMEOUT = 0.5
|
||||||
|
# devices may reply a lot slower, as the call has to go wireless to them and come back
|
||||||
_DEVICE_REQUEST_TIMEOUT = DEFAULT_TIMEOUT
|
_DEVICE_REQUEST_TIMEOUT = DEFAULT_TIMEOUT
|
||||||
_PING_TIMEOUT = 5000
|
# when pinging, be extra patient
|
||||||
|
_PING_TIMEOUT = DEFAULT_TIMEOUT * 2
|
||||||
|
|
||||||
#
|
#
|
||||||
# Exceptions that may be raised by this API.
|
# Exceptions that may be raised by this API.
|
||||||
|
@ -178,6 +181,9 @@ def read(handle, timeout=DEFAULT_TIMEOUT):
|
||||||
"""Read some data from the receiver. Usually called after a write (feature
|
"""Read some data from the receiver. Usually called after a write (feature
|
||||||
call), to get the reply.
|
call), to get the reply.
|
||||||
|
|
||||||
|
:param: handle open handle to the receiver
|
||||||
|
:param: timeout how long to wait for a reply, in seconds
|
||||||
|
|
||||||
:returns: a tuple of (devnumber, message data), or `None`
|
:returns: a tuple of (devnumber, message data), or `None`
|
||||||
|
|
||||||
:raises NoReceiver: if the receiver is no longer available, i.e. has
|
:raises NoReceiver: if the receiver is no longer available, i.e. has
|
||||||
|
@ -199,6 +205,8 @@ def _read(handle, timeout):
|
||||||
unloaded. The handle will be closed automatically.
|
unloaded. The handle will be closed automatically.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
# convert timeout to milliseconds, the hidapi expects it
|
||||||
|
timeout = int(timeout * 1000)
|
||||||
data = _hid.read(int(handle), _MAX_READ_SIZE, timeout)
|
data = _hid.read(int(handle), _MAX_READ_SIZE, timeout)
|
||||||
except Exception as reason:
|
except Exception as reason:
|
||||||
_log.error("read failed, assuming handle %r no longer available", handle)
|
_log.error("read failed, assuming handle %r no longer available", handle)
|
||||||
|
@ -230,6 +238,7 @@ def _skip_incoming(handle, ihandle, notifications_hook):
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
|
# read whatever is already in the buffer, if any
|
||||||
data = _hid.read(ihandle, _MAX_READ_SIZE, 0)
|
data = _hid.read(ihandle, _MAX_READ_SIZE, 0)
|
||||||
except Exception as reason:
|
except Exception as reason:
|
||||||
_log.error("read failed, assuming receiver %s no longer available", handle)
|
_log.error("read failed, assuming receiver %s no longer available", handle)
|
||||||
|
@ -248,6 +257,7 @@ def _skip_incoming(handle, ihandle, notifications_hook):
|
||||||
if n:
|
if n:
|
||||||
notifications_hook(n)
|
notifications_hook(n)
|
||||||
else:
|
else:
|
||||||
|
# nothing in the input buffer, we're done
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
@ -319,10 +329,12 @@ def request(handle, devnumber, request_id, *params):
|
||||||
_skip_incoming(handle, ihandle, notifications_hook)
|
_skip_incoming(handle, ihandle, notifications_hook)
|
||||||
write(ihandle, devnumber, request_data)
|
write(ihandle, devnumber, request_data)
|
||||||
|
|
||||||
|
# we consider timeout from this point
|
||||||
|
request_started = _timestamp()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
now = _timestamp()
|
|
||||||
reply = _read(handle, timeout)
|
reply = _read(handle, timeout)
|
||||||
delta = _timestamp() - now
|
delta = _timestamp() - request_started
|
||||||
|
|
||||||
if reply:
|
if reply:
|
||||||
report_id, reply_devnumber, reply_data = reply
|
report_id, reply_devnumber, reply_data = reply
|
||||||
|
@ -374,6 +386,15 @@ def request(handle, devnumber, request_id, *params):
|
||||||
n = make_notification(reply_devnumber, reply_data)
|
n = make_notification(reply_devnumber, reply_data)
|
||||||
if n:
|
if n:
|
||||||
notifications_hook(n)
|
notifications_hook(n)
|
||||||
|
# elif _log.isEnabledFor(_DEBUG):
|
||||||
|
# _log.debug("(%s) ignoring reply %02X [%s]", handle, reply_devnumber, _strhex(reply_data))
|
||||||
|
|
||||||
|
# a reply was received, but did not match our request in any way
|
||||||
|
# reset the timeout starting point
|
||||||
|
request_started = _timestamp()
|
||||||
|
|
||||||
|
# if _log.isEnabledFor(_DEBUG):
|
||||||
|
# _log.debug("(%s) still waiting for reply, delta %f", handle, delta)
|
||||||
|
|
||||||
if delta >= timeout:
|
if delta >= timeout:
|
||||||
_log.warn("timeout on device %d request {%04X} params[%s]", devnumber, request_id, _strhex(params))
|
_log.warn("timeout on device %d request {%04X} params[%s]", devnumber, request_id, _strhex(params))
|
||||||
|
@ -403,10 +424,12 @@ def ping(handle, devnumber):
|
||||||
_skip_incoming(handle, ihandle, notifications_hook)
|
_skip_incoming(handle, ihandle, notifications_hook)
|
||||||
write(ihandle, devnumber, request_data)
|
write(ihandle, devnumber, request_data)
|
||||||
|
|
||||||
|
# we consider timeout from this point
|
||||||
|
request_started = _timestamp()
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
now = _timestamp()
|
|
||||||
reply = _read(handle, _PING_TIMEOUT)
|
reply = _read(handle, _PING_TIMEOUT)
|
||||||
delta = _timestamp() - now
|
delta = _timestamp() - request_started
|
||||||
|
|
||||||
if reply:
|
if reply:
|
||||||
report_id, reply_devnumber, reply_data = reply
|
report_id, reply_devnumber, reply_data = reply
|
||||||
|
|
|
@ -98,11 +98,11 @@ class _ThreadedHandle(object):
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
|
||||||
# How long to wait during a read for the next packet.
|
# How long to wait during a read for the next packet, in seconds
|
||||||
# Ideally this should be rather long (10s ?), but the read is blocking
|
# Ideally this should be rather long (10s ?), but the read is blocking
|
||||||
# and this means that when the thread is signalled to stop, it would take
|
# and this means that when the thread is signalled to stop, it would take
|
||||||
# a while for it to acknowledge it.
|
# a while for it to acknowledge it.
|
||||||
_EVENT_READ_TIMEOUT = 500
|
_EVENT_READ_TIMEOUT = 0.5
|
||||||
|
|
||||||
# After this many reads that did not produce a packet, call the tick() method.
|
# After this many reads that did not produce a packet, call the tick() method.
|
||||||
# This only happens if tick_period is enabled (>0) for the Listener instance.
|
# This only happens if tick_period is enabled (>0) for the Listener instance.
|
||||||
|
|
Loading…
Reference in New Issue