Hey folks!
Today, I'd like to share with you a new features we are about to push on Fernand that has been bothering us for a while.
When we were pushing a new version of Fernand in Production, the app tended to have some issues there and there caused by some cache.
So we wanted to implement a notification to tell the user that a new version was released, and they had to refresh their browser.
That's what I worked on today, but I was surprised about the suggestion available online.
Indeed, if your frontend is independant from the backend, how can you tell your frontend that a new version is available?
Well, simple! You just have to create an endpoint on your backend that will receive a Webhook notification on PUSH from Github/Gitlab/etc.
When receiving the request, the server will have a few work to do:
- Save locally the new version, in case of reload
- Send it to the users when they connects
- Send it to the currently connected users.
For both 2 and 3, I searched online, and found two main possibilities:
- Using a WebWorker
- Having an endpoint in the backend that will show the latest version and compare it with the front. Show the notification when it differ.
Even though option 1 makes a bit more sense, option 2 is really bad because it requires the frontend to query the backend every X minutes, which might cause a DDoS on the server as the app grows in popularity.
Moreover, it's absolutely not efficient, since the delay between two updates could be weeks, months or even years on old projects!
But I wasn't a fan of WebWorker neither, because it required installing it on all the browsers, and the update were only interesting when our users were using Fernand only.
So I come up with another idea. Fernand is relying on WebSockets to exchange data (but stay tuned for a solution when using REST API), so all I had to do, is send a notification to all connected users telling them about the new version.
On the frontend, what I did was store the current SHA1 COMMIT ID as a javascript variable, and compare that to the version sent by the server. If it differs, it means there is a new version available and we show the "Refresh" notification.
The current version is first sent by the WebSocket when the user connects, and when a new version is released, that same Websocket will send the same event with the updated version. That way, in the frontend, we use the same code for both scenarios.
Implementing that in the frontend was relatively easy (I had a much more difficult time finding a way to get the commit ID saved on the app).
But what do to if you are not using Websockets?
In this case, an easy alternative is to provide the current known version of your app as an header when sending your responses back to the client. On the frontend, you can setup a request interceptor to read the responses and compare the "app version header" to the local one and trigger the notification when it differ.
This avoids you to have to setup an interval to check your server.
And in case your user doesn't send much requests to your server, you can query the version to your server when the user gives focus to your app.
So in the end, we have the following workflow at Fernand:
- We push an update to Github for the app
- Github sends a Webhook event to our servers (dev/prod/etc)
- The server will check if the branche matches the server type (branch staging for the staging servers, etc)
- If it does, we wait for a few minutes, while the build completes
- The new SHA1 COMMIT ID is then saved locally, and an event is sent to all connected websocket to provide the new version
On the frontend, when receiving an event from the websocket about the version, we simply compare the local one against the new one, and if it differs, we show the notification!
Easy peasy :)
Top comments (0)