Search code examples
pythonflaskwebsocketsocket.ioflask-socketio

Flask-SocketIO connection gets interrupted when code execution takes too long


Hi my conversion finished stops arriving on the client side once the code execution takes too long.

This works:

@socketio.on('nifti_conversion')
def handle_message(message):
    elehelper.send_status({'code': 201, 'message':'conversion started!'})
    sleep(5)
    elehelper.send_status({'code': 202, 'message':'conversion finished!'})

while the following fails:

@socketio.on('nifti_conversion')
def handle_message(message):
    elehelper.send_status({'code': 201, 'message':'conversion started!'})
    sleep(120)
    elehelper.send_status({'code': 202, 'message':'conversion finished!'})

also note that this works:

@socketio.on('nifti_conversion')
def handle_message(message):
    elehelper.send_status({'code': 201, 'message':'conversion started!'})
    socketio.sleep(120)
    elehelper.send_status({'code': 202, 'message':'conversion finished!'})

First I expected some kind of timeout but the disconnect happened after varying times..so far I observed 90, 94, 100, 104 seconds.

On the client side the console looks like following.

Working 5 seconds case: enter image description here

Failing 120 seconds case:

enter image description here


Solution

  • There is ping_timeout parameter for SocketIO that has default value 60 seconds. You can play with it to adjust wait time.

    However for executing any long operations, it is recommended not to block current thread since it is blocking next requests.

    Consider any of next approaches for your implementation:

    1. Async execution using threads or separate processes https://docs.python.org/3/library/concurrent.futures.html
    2. Celery based background tasks http://flask.pocoo.org/docs/0.12/patterns/celery
    3. Asyncio's coroutine http://flask-aiohttp.readthedocs.io/en/latest/coroutine.html