Flask socket IO - asynchronous execution log delivery to client

Viewed 50

We got some asynchronous jobs that can be scheduled and produce logs as each job executes. For example, say a job ID 100 is scheduled to run and the logs are stored in some database as the job executes. The client/browser is interested in tracking/seeing new logs as they become available say for the job 100. The client emits an event say log-for-run with value 100 and that is handled by socketio.on at flask and can emit log messages.

  1. How do we handle publishing of logs continuously as they become available (say it takes 10 min for the run to complete)
  2. How do we stop/release gunicorn thread once the run completes and all logs are already emitted to client / user agent?

I believe below implementation may not be desirable

@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)

EDIT:

Or should the solution be handled in below way?

  1. On connect event from client, spin up a background daemon thread

  2. the background thread continues to look for new logs for a given run ID and somehow emit logs against the appropriate session ID so that it stays in the socketio queue waiting to be delivered

  3. On disconnect event from client, shut down background thread.

  4. also have a mechanism to shutdown background thread if there won't be anymore new logs or some longer time period has elapsed

0 Answers
Related