-
-
Notifications
You must be signed in to change notification settings - Fork 892
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Client doesn't receive messages from server when sent from separate thread #434
Comments
This happens because you are mixing greenlets with threads. You need to follow that advice on monkey patching, or else use the eventlet API to start your background tasks, so that they are also greenlets. Regarding the infinite recursion error, have you tried downgrading eventlet to 0.17.4 like others have done? Lastly, if you don't see the |
Thanks for the quick response. I do see the I tried spawning an eventlet thread like eventlet.spawn(check_sim_status, sb.event_queue) and now the Exception in thread Thread-4:
Traceback (most recent call last):
File "C:\Users\reedt\AppData\Local\Programs\Python\Python36\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "C:\Users\reedt\AppData\Local\Programs\Python\Python36\lib\threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\reedt\AppData\Local\Programs\Python\Python36\lib\multiprocessing\pool.py", line 365, in _handle_workers
while thread._state == RUN or (pool._cache and thread._state != TERMINATE):
AttributeError: '_MainThread' object has no attribute '_state'
Exception in thread Thread-5:
Traceback (most recent call last):
File "C:\Users\reedt\AppData\Local\Programs\Python\Python36\lib\multiprocessing\pool.py", line 381, in _handle_tasks
if thread._state:
AttributeError: '_MainThread' object has no attribute '_state'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\reedt\AppData\Local\Programs\Python\Python36\lib\threading.py", line 916, in _bootstrap_inner
self.run()
File "C:\Users\reedt\AppData\Local\Programs\Python\Python36\lib\threading.py", line 864, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\reedt\AppData\Local\Programs\Python\Python36\lib\multiprocessing\pool.py", line 401, in _handle_tasks
cache[job]._set(ind + 1, (False, ex))
TypeError: unsupported operand type(s) for +: 'NoneType' and 'int' It occurred to me that I'm using the multiprocessing module somewhere in my program, with Now, other |
This behavior is so strange. Without monkey patching, my main thread hangs on the Jeez. I finally just uninstalled eventlet and gevent, and now my program is working perfectly well (so, without Websockets?). The performance is definitely slow. |
But you lost the ability to use WebSocket. I think the problem is that you are expecting a multi-threaded app to translate automatically to eventlet, and it isn't that easy. There are many functions from the standard library that aren't compatible, you are probably using some of those. Monkey patching makes most of the library compatible, but there are still some things that eventlet cannot do. The multiprocessing stuff that you are apparently using is definitely a suspect. I think if/when you decide to switch to eventlet, you have to convert that into something that is more appropriate for an async framework. |
This is definitely true. I just don't understand why importing and using eventlet (without monkey patching) on a background thread that just interacts with a queue would change how the parts of my program function that do not interact with eventlet at all. I reinstalled eventlet to the latest version and spawned my background thread using |
I'm going to do some more work porting some of my underlying code over to eventlets once I do some more reading on them, now that I know I have to go all-or-nothing with this library. I'm pretty sure my previous comment is false, that code is not working properly just replacing the call to thread with eventlet. |
Well, for starters, eventlet is a single-threaded framework. Anything that interacts in any way with eventlet must be all on the same thread. You can use other threads, I guess, but there must be no interaction between the eventlet thread (usually the main thread) and your other threads, unless you manage that interaction exclusively through eventlet. The reason for all these conditions is that for eventlet to function only non-blocking functions must be used. A lot of the standard library functions are blocking, so any blocking call that you make will prevent eventlet from running. And this, can be the reason why your emits are not working. |
I don't have any terribly blocking I/O on my main thread. My program uses subprocess and thread pools to do expensive work in another program, and wait on the results, but this processing does not touch socket.io. Now, I've stripped out all manually created threads and eventlet entirely from my reporter. It now calls the def report_sim_update(message):
print("MESSAGE IN SITE: " + str(message))
socketio.emit("progressbar", json.dumps(message)) and internally self._notifier_function({
"player": player["name"],
"done:": True
}) I'm sorry I'm posting a lot on this thread, I'm just surprised by the complexity using this library. It really doesn't seem that nuanced of a problem on the surface. |
Hello,
I've done a lot of digging on the issue of using different threads with Flask-SocketIO. I feel like my problem is incredibly simple, although it's possible I'm missing something conceptually important.
I'm trying to send a message to the client using a background thread, which reads from an event queue, like this:
Socket.io seems to ignore the emit call, no debug line is printed and the program goes on its way. Other calls within decorators communicate with the client site just fine.
Originally I was just using standard python threads for this event queue, but other posts (such as miguelgrinberg/python-socketio#16) talked about monkey patching with eventlet, so I tried that as well. I got the infinite recursion bug (as seen here eventlet/eventlet#371), so I couldn't proceed.
Another post recommended adding
socketio.sleep(0)
after my emit, but the message does not show up on the client, and it additionally throws a greenlet exception:Is there something obvious I'm doing wrong? I don't have any performance requirements right now, I just want to send a message from a background thread.
The text was updated successfully, but these errors were encountered: