You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Right now we have a simple way for packets to be read from the BLED112. We have a dedicated thread that reads packets and puts them on a queue. The BLED112CommandProcessor runs in its own thread and blocks when it needs a packet on queue.get(). Packets are always processed one at a time.
For moving to asyncio, we need to instead give packets to OperationManager as input so that they can be used to unblock any running coroutine operations. OperationManager.process_message() must only be called from within the event loop itself, so we need an efficient way to hand packets from the ReaderThread to the event loop.
The obvious way would be to call add_callback_threadsafe for each packet but that means many locked callback adds as packet volumes increase. An alternative would be to batch packets with a timeout but that risks increasing latency when we are waiting for just 1 packet in and not many packets are coming.
An intermediate option is to share packets using an unlocked deque and have a handler scheduled that empties out the deque whenever it is run. A separate shared boolean flag notes if the handler has run since the last invocation so that the ReaderThread can avoid queuing it again since it will get all packets once it runs:
Important: The ordering of setting is_sched is important to make sure there is no race condition where a packet could be added to the deque but no callback scheduled after that time. The logic has been thought through in the above diagram but not formally proven to be correct so it should be rechecked before implementation.
The text was updated successfully, but these errors were encountered:
Right now we have a simple way for packets to be read from the BLED112. We have a dedicated thread that reads packets and puts them on a queue. The BLED112CommandProcessor runs in its own thread and blocks when it needs a packet on
queue.get()
. Packets are always processed one at a time.For moving to asyncio, we need to instead give packets to
OperationManager
as input so that they can be used to unblock any running coroutine operations.OperationManager.process_message()
must only be called from within the event loop itself, so we need an efficient way to hand packets from theReaderThread
to the event loop.The obvious way would be to call
add_callback_threadsafe
for each packet but that means many locked callback adds as packet volumes increase. An alternative would be to batch packets with a timeout but that risks increasing latency when we are waiting for just 1 packet in and not many packets are coming.An intermediate option is to share packets using an unlocked
deque
and have a handler scheduled that empties out the deque whenever it is run. A separate shared boolean flag notes if the handler has run since the last invocation so that theReaderThread
can avoid queuing it again since it will get all packets once it runs:The text was updated successfully, but these errors were encountered: