Question: flask-socket.io keep's background task ( socketio.start_background_task ) running even after the client has left or disconnected.
Is there some way to immediately close a background tasks after some on has left?
You can code your background task so that it checks an Event object at regular intervals and exits when the event has been signaled. Then you can signal the event from the disconnect handler when your user leaves.
I am confused by what you mean, is there an example of this?
@yusuf8ahmed This stack overflow answer has an example: https://stackoverflow.com/a/49877671/904393.
I am still kinda confused as this is a threading example, while I am using (start_background_task) like this.
#? display the "/home" dashboard
def dash_main_info(tokens):
ws = Wsimple.access(verbose=True)
while True:
try:
dashboard = ws.dashboard(tokens)
socketio.sleep(TIME)
socketio.emit('main_dashboard_info', dashboard, namespace='/dashboard')
except InvalidAccessTokenError as e:
try:
ws = Wsimple.access()
tokens = ws.refresh_token(tokens)
except InvalidRefreshTokenError as e:
socketio.emit('invalid_token', namespace='/dashboard')
break
@socketio.on('dashboard', namespace='/dashboard')
def soc_dashboard():
global thread
with thread_lock:
if thread is None:
if isinstance(session.get('key'), list):
print(f"Starting dashboard key {session.get('key')}")
thread = socketio.start_background_task(dash_main_info, session['key'])
else:
print("Starting dashboard false key")
socketio.emit('invalid_token', namespace='/dashboard')
The idea is the same though. The Event object can be used to tell the thread when it needs to exit. If you use eventlet, then you have to use the Event object from eventlet, and the same for gevent, but other than that the concept is the same, somewhere inside the loop that you have in your thread you have to check if the event object has been signaled, and in that case exit the loop.
This project is not using eventlet or gevent, but I think I understand what you mean, I would have to put some type of signal that would cause the while loop to break. Could this work?
def dash_main_info(tokens):
ws = Wsimple.access(verbose=True)
while True:
if DASH == True:
try:
dashboard = ws.dashboard(tokens)
socketio.sleep(TIME)
socketio.emit('main_dashboard_info', dashboard, namespace='/dashboard')
except InvalidAccessTokenError as e:
try:
ws = Wsimple.access()
tokens = ws.refresh_token(tokens)
except InvalidRefreshTokenError as e:
socketio.emit('invalid_token', namespace='/dashboard')
break
@socketio.on('close_dashboard', namespace='/dashboard')
def soc_close_dashboard():
DASH = False
@yusuf8ahmed use an Event object, not a global variable.
In my current application I neither import/use gevent or eventlet. Which one should I use?
but when I am testing WebSockets I use ''gunicorn -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 4 app:app"
I think threading.Event will work for you, because when you use Gunicorn it'll be monkey patched to be compatible with Gevent.
Is there an example of someone doing this? using threading.Event and socketio.start_background_task together
I just recorded a short video showing how to kill a thread, since this is a question I get often. https://www.youtube.com/watch?v=A97QLHAqNuw
Thank you very much for making this video for me. I really appreciate that. I may have a few more questions about threading and socket.io as they are new topics to me 馃槃.
And I am also planning on making a pr to update the example folder 馃憖 鉁旓笍