Skip to content
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

gevent.pywsgi fails to inform which random port it uses when given port 0 #1998

Open
hcs-catchscan opened this issue Sep 27, 2023 · 0 comments

Comments

@hcs-catchscan
Copy link

Environment

  • gevent version: 23.9.1 from pypi installed using pip in venv
  • Python version: 3.11.4 installed from Ubuntu main repos
  • Operating System: Ubuntu 23.04 on x86-64 running kernel 6.2.0-33-generic

Description:

I'm trying to accommodate the faily simple use case of printing which port a server is running on on startup. This works completely fine when you tell gevent which port to use, but fails when gevent picks a random port.
I suspect the reason is that gevent waits until the serve_forever call to call bind, meaning it's not available ahead of time.

When telling gevent to bind on port 0 and then asking what port it has bound to it reports 0, which is verifiably false. Running ss -putan | grep python after starting the server reveals that gevent is listening on a random high-range port (as it should).

WSGI Provided Port Random Port
Werkzeug ✔️ ✔️
gevent ✔️

What I've run:

The following snippet should highlight the issue. When running the script, note that you will have to issue keyboard interrupts to enumerate the 4 servers. (Press CTRL+C four times)

Requires: gevent flask

from flask import Flask
from gevent.pywsgi import WSGIServer
from werkzeug.serving import make_server


def __build_app() -> Flask:
    app = Flask(__name__)
    @app.route('/')
    def hello(): return 'Hello World'
    return app


def demo_werkzeug(port: int):
    server = make_server('127.0.0.1', port, __build_app())
    print(f'Werkzeug server running on {server.server_name}:{server.server_port}')
    server.serve_forever()


def demo_gevent(port: int):
    server = WSGIServer(('127.0.0.1', port), __build_app())
    print(f'gevent server running on {server.server_host}:{server.server_port}')
    try:
        server.serve_forever()
    except KeyboardInterrupt:
        pass


if __name__ == '__main__':
    demo_werkzeug(8080)  # Works
    demo_gevent(8080)  # Works
    demo_werkzeug(0)  # Works
    demo_gevent(0)  # Doesnt work

The console output should look something like this:

Werkzeug server running on localhost:8080
gevent server running on 127.0.0.1:8080
Werkzeug server running on localhost:37619
gevent server running on 127.0.0.1:0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant