#heroku #redis #&unicorn #plotly-dash
#heroku #redis #&unicorn #сюжетно-dash
Вопрос:
Я хочу создать веб-приложение в Dash, которое выполняет дорогостоящую вычислительную задачу на вводимых пользователем данных и возвращает результат в табличном формате. На интерфейсной стороне у меня есть обратный вызов Dash, который обновляет компоненты Dash на основе входных данных от компонентов Dash, например:
from rq import Queue
from worker import conn
import time
# redis connection to execute tasks in the back&round
q = Queue(connection=conn,job_timeout='3m')
@app.callback(
[Output('table-columns', 'columns'),
Output('table-columns', 'data'),],
[Input('upload', 'contents'),
Input('launch-expensive-job-button', 'n_clicks')],
)
def expensive_task(contents, n_clicks_launch):
df = q.enqueue(expensive_function, contents).result
while df is None:
time.sleep(2)
return [{"name": i, "id": i} for i in df.columns], df.to_dict("rows")
Я использую очередь Redis для выполнения задачи в фоновом режиме. Как только результат обновляется в переменной df (по соглашению Redis, результат отсутствует во время обработки), я возвращаю его клиенту. Проблема в том, что моя платформа развертывания не позволяет интерфейсным заданиям выполняться слишком долго. Поэтому, даже если я отправляю задание на серверную часть, мне нужно найти способ заставить приложение Dash прослушивать любые обновления переменной df.
Я уверен, что решение где-то доступно, но я слишком новичок, чтобы найти его. Рад, что мне указали на некоторую документацию, в которой я мог бы сориентироваться.
Ответ №1:
Я думаю, вы ищете Interval
компонент (документация здесь). Это запускает обновление клиента с регулярным интервалом, например, один раз в секунду. Обратный вызов будет выглядеть следующим образом,
...
Interval(id='tri&&er', interval=1000) # must be in the app layout
...
@app.callback(Output(...), [Input('tri&&er', 'n_intervals')])
def poll_update(n_intervals):
# check status of redis here and update the output accordin&ly
Комментарии:
1. Спасибо за ответ,
Interval
компонент — это определенно правильный путь. Двигаясь вперед с этим, не могли бы вы предложить способ заставить обратный вызов сInterval
компонентом прослушивать обновления из переменной df, кроме как делать переменную глобальной? В настоящее время я все еще обязан хранить df локально, поскольку это довольно большой набор данных, поэтому было бы здорово, если бы я мог передать его непосредственно в обратный вызов. Большое спасибо!