-
Notifications
You must be signed in to change notification settings - Fork 452
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
TypeError Cannot read properties of null (reading 'callback')
when receiving subscribe response with no inflight subscribe
#605
Comments
Okay, I think I'm getting somewhere with this. The issue appears to be to do with our reconnecting websocket. It looks like this series of events is happening:
There's a lot of moving parts here, but I'm pretty sure this is the rough shape of the problem. This could well be a bug in our reconnecting socket library, but regardless of that, I guess it raises a question around how ShareDB should act before its handshake has completed: should the server just bin any messages we receive before this? The client already tries to avoid sending messages before the handshake, so we should be able to assume anything sent before the handshake is rubbish? |
Ha yes, okay I guess this is probably a valid thing for a reconnecting socket to do in order to keep its API roughly aligned with a "vanilla" Still, I think we should make ShareDB behave "sensibly" if clients decide to retry messages on reconnection, before the handshake has happened. Will put together a PR and we can discuss there I guess. |
Hmm had a very quick look at this and actually I'm not sure how best to do this without making a breaking change to our protocol. Outline of v1.0 vs 1.1 protocol here: #341 The crux of it is that v1.0 just sends an A v1.1 server can disregard any messages it receives before the client's
We could potentially do something like buffer for some time, or Maybe we should just do something simple like log a warning if an |
At the moment, it's possible for messages to be sent before the client- server handshake. Sending messages before the handshake has happened has undefined behaviour, and can result in errors such as in: #605 We can't just ignore these messages, because old clients might potentially be on v1.0 of the client-server protocol, in which the server informs the client when it's ready, but not the other way around, so it's impossible to know when a client should be considered "ready", and its messages acceptable. Instead, we add a warning for clients on v1.1 who have sent a message before their handshake. In order to aid with debugging, we keep track of the first message received, and log it when the handshake is received (which means that v1.0 clients will never get such a warning).
In our docs, we recommend using [`reconnecting-websocket`][1] to handle websocket reconnection. However, [by default][2] that library will [buffer][3] messages when its underlying socket is closed, which can lead to [undefined behaviour][4] when ShareDB reconnects, since it works under the assumption that all messages sent as the socket is closing have been lost (eg pushing inflight ops back onto the pending queue, etc.). This change updates our documentation and our examples to set `{maxEnqueuedMessages: 0}`, which disables this buffering, and should help to avoid ShareDB reaching undefined states when reconnecting using this library. [1]: https://www.npmjs.com/package/reconnecting-websocket [2]: https://github.com/pladaria/reconnecting-websocket/blob/05a2f7cb0e31f15dff5ff35ad53d07b1bec5e197/reconnecting-websocket.ts#L46 [3]: https://github.com/pladaria/reconnecting-websocket/blob/05a2f7cb0e31f15dff5ff35ad53d07b1bec5e197/reconnecting-websocket.ts#L260 [4]: #605
At the moment, it's possible for messages to be sent before the client- server handshake. Sending messages before the handshake has happened has undefined behaviour, and can result in errors such as in: #605 We can't just ignore these messages, because old clients might potentially be on v1.0 of the client-server protocol, in which the server informs the client when it's ready, but not the other way around, so it's impossible to know when a client should be considered "ready", and its messages acceptable. Instead, we add a warning for clients on v1.1 who have sent a message before their handshake. In order to aid with debugging, we keep track of the first message received, and log it when the handshake is received (which means that v1.0 clients will never get such a warning).
Alec says it's when the sharedb client tries to send data while the socket is in CLOSING. Unfortunately there's no 'closing' event. In addition to the server change above, we are also considering specifically having the client check for |
We're getting this error:
The error is happening because a subscribe response is being received over the WebSocket, but there's no
inflightSubscribe
set.I've rummaged around in the code (which I wrote 😅 🙈 ) and I'm not really sure how we get into this state.
As far as I can tell:
!!connection.canSend
inflightSubscribe
is put back into thependingSubscribe
queueinflightSubscribe
, which only happens:The text was updated successfully, but these errors were encountered: