question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Client doesn't receive messages from server when sent from separate thread

See original GitHub issue

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:

@app.route("/all_sims/", methods=["GET"])
def all_sims():
   ...

   t = threading.Thread(target=check_sim_status, args=(sb.event_queue,), daemon=True)
   t.start()

# thread target
def check_sim_status(queue):
    while True:
        message = queue.get()
        print("MESSAGE IN SITE: " + str(message))
        # with app.app_context():
        socketio.emit("progressbar", json.dumps(message))
        socketio.sleep(0)

        queue.task_done()

if __name__ == "__main__":
    socketio.run(app, debug=True)

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 https://github.com/miguelgrinberg/python-socketio/issues/16) talked about monkey patching with eventlet, so I tried that as well. I got the infinite recursion bug (as seen here https://github.com/eventlet/eventlet/issues/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:

Traceback (most recent call last):
  File "C:\Users\reedt\AppData\Local\Programs\Python\Python36\lib\site-packages\eventlet\queue.py", line 118, in switch
    self.greenlet.switch(value)
greenlet.error: cannot switch to a different thread

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.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:3
  • Comments:8 (3 by maintainers)

github_iconTop GitHub Comments

5reactions
Heanthorcommented, Mar 22, 2017

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 socketio.emit function directly, I’ve verified the method is called correctly, but I still don’t see any messages being sent or coming through. The handshake is done just fine. I’m not sure there’s a simpler use case than this:

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.

2reactions
miguelgrinbergcommented, Mar 22, 2017

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.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Multi-threaded client not receiving messages from server
In order to do this, I have tried to set up two threads on the client-side, one for receiving, and one for sending....
Read more >
Threads and Sockets in Python | p4-mapreduce
The Python socket library facilitates sending and receiving messages over a network. First, we'll create a TCP server that receives messages and a...
Read more >
Message Passing
These subservers each send a message to the server, but the server doesn't reply to them until it gets a request from a...
Read more >
Javanotes 9, Section 12.4 -- Threads and Networking
A network client program that sends requests to a server might get by with a single thread, if it has nothing else to...
Read more >
Writing the Server Side of a Socket (The Java™ Tutorials ...
The Java runtime automatically closes the input and output streams, the client socket, and the server socket because they have been created in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found