Skip to content

Resolve "Show error if the websocket reconnecting loop stops"

Closes #361 (closed)

The reason why I have been improving this process with this merge request and also https://gitlab.com/bramw/baserow/-/merge_requests/187 is because there are people who keep their browser 24/7 and they have a tab of Baserow open. Somehow, something went wrong while refreshing their authentication token which means that they can't connect to the backend WebSocket server. Before they would always stay in a reconnect loop which requests WebSocket connections from the backend while the token is null or not valid anymore. This needs to be prevented. The web-frontend should not stay in a reconnect loop indefinitely. It should be communicated clearly to the user that the connection has failed asking him to refresh the page. Refreshing the page would redirect the user back to the login page.

Changes

  • Attempt only 10 times to reconnect instead of indefinite.
  • Do not reconnect if we already know the token is invalid.
  • Do not reconnect if the token is null.
  • Show a message to the user if the connection has failed.

How to test

  • Decrease the JWT token expiration time to 30 seconds.
import datetime
JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=30),
    'JWT_ALLOW_REFRESH': True,
    'JWT_REFRESH_EXPIRATION_DELTA': datetime.timedelta(days=7),
    'JWT_RESPONSE_PAYLOAD_HANDLER': 'baserow.api.user.jwt.'
                                    'jwt_response_payload_handler'
}
  • Visit a table page using your browser.
  • Stop the backend Django server so that the web-frontend can't refresh the token.
  • After 30 seconds, start the backend server again.
  • The web-frontend should detect that the token isn't working anymore and should show a correct message to the user asking him to refresh.
  • The web-frontend should not keep trying to connect to the backend indefinitely.

Additional fixes

While working on the WebSocket part I also figured out why we get al these code=100X (going away) errors in Sentry. This had to do with the fact that when the connection was already disconnected, the server tried to send one last confirmation that the connection has been discarded from a page. This could easily be fixed by not sending that message when the user user socket is disconnected.

This can be tested by running the development server with gunicorn -w 1 -b 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker baserow.config.asgi:application --log-level=debug in the backend container. Then visit a table page http://localhost:3000/database/1/table/1 and when loaded try to refresh the page. If you have checked out the new changes, you should not see any errors.

This merge request should fix all our WebSocket problems 🎉

Edited by Bram Wiepjes

Merge request reports