Conversation
63c1f05 to
2376d76
Compare
|
There's a much more serious problem here in that the async WebSocket library being used don't support concurrent send and receive. Socket reads time out after 30 seconds and I'm only listening for events which means that if there isn't an event every 30 seconds the connection is closed with a If I try to send pings to keep the connection active this doesn't work because my ping is stuck waiting for a lock in If there are multiple tasks listening for events and one of them tries to send a request because of an event, it will be blocked until the next message is received because one of the other tasks will be trying to receive its next message. |
If there are multiple async tasks trying to read from the WebSocket, messages spread across multiple chunks won't be handled correctly because they each independently try to combine chunks. Only one of the multiple tasks can be successful, leaving the others starved of responses because they'll all try to read one message and won't react if a new message has already been received for them by another task. Use a lock to ensure that only one of the tasks can be reading at any one time, and wake up the other tasks whenever there's a new message. Closed WebSockets are handled by having each task becoming the active reader in turn to discover that the connection has been closed.
2376d76 to
4668160
Compare
|
Can you provide a minimal script that presents this behavior please? Would like to do some validation myself. |
|
This script subscribes to area events that happen rarely. It will throw an error when the socket read times out after 30 seconds. Bug 1: Pinging every second should avoid socket reads timing out but the send for the ping is blocked waiting on the recv for the event listener. While investigating the code for receiving messages, I found the following two bugs. This is an upstream issue in the async websocket library because it can't do send and receive concurrently (content warning: description contains AI slop, jawah/urllib3.future#400). If there's more than one async task trying to read (which you can do by having multiple event listeners) then all of them will call Inside Bug 2: There are multiple tasks all calling Bug 3: There are multiple tasks all calling |
|
I am hesitant to make modifications to this client due to a deficiency in an upstream library. I see there is some discussion there, can we drive there first to see if we can fix the source? If we don't get traction there, I am willing to look at options here. |
There's a bug in this library's handling of reads and upstream's locking of reads and writes. |
If there are multiple async tasks trying to read from the WebSocket, messages spread across multiple chunks won't be handled correctly because they each independently try to combine chunks.
Only one of the multiple tasks can be successful, leaving the others starved of responses because they'll all try to read one message and won't react if a new message has already been received for them by another task.
Use a lock to ensure that only one of the tasks can be reading at any one time, and wake up the other tasks whenever there's a new message. Closed WebSockets are handled by having each task becoming the active reader in turn to discover that the connection has been closed.