Long running Callbacks

Long running callbacks

Tasks in web applications can be time-consuming, causing communication timeouts between the server (Python application) and the client (web browser).

To overcome this challenge, Taipy offers a powerful feature called “long-running callbacks” to overcome this challenge. These callbacks enable the server to perform heavy tasks asynchronously while keeping the user interface responsive. This article explores the concept of long-running callbacks in Taipy, providing implementation examples and highlighting their usefulness in enhancing the user experience.

Example 1: Executing a Heavy Task in the Background

Let’s consider a scenario where a callback triggers a resource-intensive task that takes time to complete. To achieve this, we can follow a simple implementation pattern:

from taipy.gui import State, invoke_long_callback, notify

def heavy_function(...):
    # Do something that takes time...
    ...

def on_action(state):
    notify(state, "info", "Heavy task started")
    invoke_long_callback(state, heavy_function, [...heavy_function arguments...])

In the above example, the Taipy function: `invoke_long_callback()` handles the heavy-duty function. It creates a background thread to execute the `heavy_function()` while allowing the rest of the application to keep running. The `on_action` function is triggered by a user action (clicking a button, for example).

Example 2: Monitoring Task Status

Additionally, notifications can be sent to the client’s browser, or visual elements can be updated based on the task’s outcome. Taipy provides a mechanism to be notified when the task finishes, as demonstrated below:

...

def heavy_function_status(state, status):
    if status:
        notify(state, "success", "The heavy task has finished!")
    else:
        notify(state, "error", "The heavy task has failed")

def on_action(state, id, action):
    invoke_long_callback(state, heavy_function, [...heavy_function arguments...],
                         heavy_function_status)

In this example, we introduce the `heavy_function_status()` function that is called by the `invoke_long_callback()` method. When the task concludes, this function is called, allowing you to provide appropriate notifications or updates to the user interface based on the success or failure of the task.

Handling heavy_function results: Updating the Application State

To update the State according to the return of the heavy_function, you can modify the heavy_function_status() function as follows:

def heavy_function_status(state, status, result):
    if status:
        notify(state, "success", "The heavy task has finished!")
        # Actualize the State with the function result
        state.result = result
    else:
        notify(state, "error", "The heavy task has failed")

We added a parameter called result, which represents the return value of the heavy_function(). When the heavy_function() completes successfully (status is True), we update the State with the result by assigning it to a state variable (e.g., state.result = result). This allows you to access the result in other parts of your application or display it to the user as needed.

Make sure that the heavy_function() returns a value. For example:

def heavy_function(...):
    ...
    return result

By updating the State with the result of the heavy_function(), you ensure that the user interface reflects the outcome of the heavy task and provides a seamless user experience.

Example 3: Tracking Task Progress

Sometimes, it’s beneficial to provide periodic updates on the progress of a long-running task. Taipy’s `invoke_long_callback()` offers a convenient way to achieve this:

...

def heavy_function_status(state, status):
    if isinstance(status, bool):
        if status:
            notify(state, "success", "The heavy task has finished!")
        else:
            notify(state, "error", "The heavy task has failed somehow.")
    else:
        notify(state, "info", "The heavy task is still running...")

def on_action(state):
    invoke_long_callback(state, heavy_function, [...heavy_function arguments...],
                         heavy_function_status, [...heavy_function_status arguments...],
                         5000)

In the above code snippet, by providing a `period` parameter, the `heavy_function_status()` function will be periodically triggered at the specified interval (e.g., every 5 seconds). This enables your user interface to display real-time updates, informing the end user about the ongoing task.

Conclusion

Taipy’s long-running callbacks greatly facilitate the management of time-consuming tasks in web applications. By executing heavy tasks asynchronously, Taipy ensures a responsive user interface and prevents potential communication timeouts. With the ability to monitor task status and provide progress updates, developers can create a seamless user experience even when dealing with heavy-duty operations.

Florian Jacta
Florian Jacta

Customer success engineer