Reload website after server reboot without intervall component

Hi,

is there a possibility to automatically reload the page in the browser after the server was rebooted?

My only idea is to use an intervall component, combined with a random number generated on each start up.
The intervall component is used as input. The random number as state.
The callback than compares the random number of the state with the current random number of the start up.
If they differ it triggers a reload via Output(“url”, location) otherwise no update.

But I don’t like overusing interval components too much. Does someone have an idea for another way?

Thank you.

Hello @mainframed,

Welcome to the community!

Here is a very basic example of how you would do this on a single server backend using a Flask request. (I set this up in JS because of the callback structure)

This is the result:

image

from dash import Dash, Input, Output, dcc, html, clientside_callback
from datetime import datetime
from flask import request

app = Dash(__name__)

server = app.server

serverRestarted = datetime.now().strftime('%Y-%m-%d %H:%M:%S')

@server.route('/serverRestart', methods=['POST'])
def serverRestart():
    if request:
        if request.json == serverRestarted:
            return {'status': 'ok', 'message': False}
    return {'status': 'ok', 'message': True}

app.layout = html.Div([
    html.Div(serverRestarted, id='syncServer'),
    dcc.Store(id='serverRestart', data=serverRestarted)
])

clientside_callback(
    """function (data) {
        async function serverRestartTest (data) {
            const restarted = await fetch('./serverRestart', {'method': 'POST', 
            headers: {'content-type': 'application/json'}, 
            'body': JSON.stringify(data)}).then(response=>response.json())
            .then(data=>{ return data; })
            if (restarted.message) {
                alert('you are running an outdated server, please refresh')
            }
        }
        setInterval(serverRestartTest, 30000, data)
        return window.dash_clientside.no_update
    }""",
    Output('serverRestart', 'id'), Input('serverRestart', 'data')
)

app.run()

Breakdown of the code, every 30 seconds we ping the server to see if out time matches the last server restart, if not, then it sends that the server was restarted. This then sends an alert to the page that they need to refresh the page.

You can use an dcc.Interval with a clientside callback too, this is just basic example, since we would still need to send a fetch request from the client in order to achieve the desired result.

In a multi backend setup, you should be storing your last real server reload in a db somewhere, and then query from the server to match the time in the client. Otherwise, you’d encounter issues if some of your backend servers get out of sync with restarting (especially in the case of a supervisor)

Hope this helps. :slight_smile:

1 Like

Thinking about this some more, you may be able to utilize websockets from dash-extensions, @Emil, do you have any thoughts on this?

1 Like

Yes, I believe you could use a websocket to trigger a refresh on disconnect, which would happen when the server restarts. However, I don’t see anything wrong with the interval component solution either :slight_smile:

3 Likes

Hi @jinnyzor

Wow. Thank you for your quick answer.
That looks like a great solution.

And I think you guys, are right. Intervall components are probably not that bad, if I reduce the time frame.

The websockets idea sounds like a good solution for reducing traffic/requests. But I’ll skip it for now, since it probably requires some proper testing on edge cases, such as when the server stays down for a longer period.

Thanks again.

Best regards,

1 Like

You can also use things like modals or whatever with a dcc.Interval and a clientside callback.

If it returns True, then just display the modal pop up and you can even place a button in the modal that the user can click to refresh.