Code Monkey home page Code Monkey logo

Comments (5)

uglybug avatar uglybug commented on June 13, 2024

Interestingly, rewriting the above code as below does work as expected. So it only seems to be an issue when you run a websocket inside a class that is a subclass of Thread, rather than in a Thread itself, necessarily:

from websockets.sync import client
from threading import Thread


def ws():
    ws = client.connect("wss://echo.websocket.org")

    for msg in ws:
        print(msg)


t = Thread(target=ws)
t.daemon = True
t.start()

print("Thread started. Now trying to exit")

exit()

# This does exit cleanly as we expect.

from websockets.

uglybug avatar uglybug commented on June 13, 2024

Actually, with a few more tests this morning, I narrowed down the issue a bit more. Seems to be if the client is passed into a Thread that runs the read loop, then that prevents process exit, even if the Thread is a daemon. So, taking the code above that exits successfully, if we simply move the instantiation of the client and pass it into the Thread then the process now cannot exit as long as the client connection is open:

from websockets.sync import client
from threading import Thread


def ws(sock):
    for msg in sock:
        print(msg)


c = client.connect("wss://echo.websocket.org")
t = Thread(target=ws, args=(c,))
t.daemon = True
t.start()

print("Thread started. Now trying to exit")

exit()
# Never exits

This is a pain as it means that we cannot have a continuous read in a daemon thread, whilst keeping the reference to the client so we can asyncronously send. Unless, as I have done in my own code to get around this, we run an async client in a daemon thread (which the documentation states is not supported).

from websockets.

mpetazzoni avatar mpetazzoni commented on June 13, 2024

I was looking into this and the reason this is happening is because the client.connect() call constructs the ClientConnection object, which starts the recv_events_thread. It does so without specifying the daemon parameter to the thread creation: https://github.com/python-websockets/websockets/blob/main/src/websockets/sync/connection.py#L86

This means this thread inherits the daemon status from its parent. So if you want the WebSocket connection's "background" thread to truly be a daemon thread, it must be created from within a thread that is itself a daemon – and the main thread of the Python program is not.

This certainly would be helpful to have noted in the docs of the sync client.

from websockets.

aaugustin avatar aaugustin commented on June 13, 2024

Perhaps the background thread should be a daemon thread? If the main thread as well as any other thread managed by the user of the library is done, there's no reason to prevent the program from exiting.


we run an async client in a daemon thread (which the documentation states is not supported).

It works. I'm discouraging it because:

  • there's little benefit to running an event loop just for one client connection;
  • many users of websockets don't have a clear mental model of what an event loop is and, as a consequence, struggle to start it in the right thread and use call_soon_threadsafe properly.

from websockets.

mpetazzoni avatar mpetazzoni commented on June 13, 2024

@aaugustin I agree, thanks for making the change! Let us know when you cut a release.

from websockets.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.