IO сокета Flask — асинхронная доставка журнала выполнения клиенту

#python #flask #flask-socketio

#питон #колба #колба-носок

Вопрос:

У нас есть несколько асинхронных заданий, которые можно планировать и создавать журналы по мере выполнения каждого задания. Например, предположим, что запланирован запуск идентификатора задания 100 , и журналы хранятся в некоторой базе данных по мере выполнения задания. Клиент/браузер заинтересован в отслеживании/просмотре новых журналов по мере их появления, скажем, для работы 100 . Клиент выдает событие, скажем log-for-run , со значением 100 , которое обрабатывается socketio.on в flask и может emit регистрировать сообщения.

  1. Как мы обрабатываем публикацию журналов непрерывно по мере их появления (скажем, для завершения запуска требуется 10 минут)
  2. Как мы останавливаем/освобождаем поток gunicorn после завершения запуска, и все журналы уже отправлены агенту клиента / пользователя?

Я считаю, что приведенная ниже реализация может быть нежелательной

 @socketio.on('read-exec-logs') def get_logs_with_continuous_polling(run_id):  created_at = None # allow to get older logs for the first time  while True:  logs = run_log_repo.get_logs(run_id, created_at)  for e in logs:  emit('exec-logs', 'run={}, msg={}'.format(e['run_id'], e['message']))  created_at = e['created_at'] # read logs that are newer to this timestamp  time.sleep(2)  

Редактировать:

Или с решением следует обращаться следующим образом?

  1. При connect событии от клиента разверните фоновый поток демона
  2. фоновый поток продолжает искать новые журналы для данного идентификатора запуска и каким-то образом выдает журналы по соответствующему идентификатору сеанса, чтобы он оставался в очереди socketio, ожидая доставки
  3. При disconnect событии от клиента выключите фоновый поток.
  4. также есть механизм для выключения фонового потока, если больше не будет новых журналов или прошел более длительный период времени