client_python icon indicating copy to clipboard operation
client_python copied to clipboard

Fix server shutdown

Open Tiino1 opened this issue 1 year ago • 1 comments

Summary: When I start a prometheus server, then stop it, then re-start it, server can not restart because port was not released. I am following steps indicated by documentation

Usecase: I need to be able to start and stop prometheus server to run a sequence of tests for an external application Each test needs to start a prometheus server, and then stop it

Steps to reproduce:

from prometheus_client import start_http_server
server, thread = start_http_server(8000)
server.shutdown()
thread.join()
server, thread = start_http_server(8000)

Error

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/.../python3.9/site-packages/prometheus_client/exposition.py", line 233, in start_wsgi_server
    httpd = make_server(addr, port, app, TmpServer, handler_class=_SilentHandler)
  File "/usr/lib64/python3.9/wsgiref/simple_server.py", line 154, in make_server
    server = server_class((host, port), handler_class)
  File "/usr/lib64/python3.9/socketserver.py", line 452, in __init__
    self.server_bind()
  File "/usr/lib64/python3.9/wsgiref/simple_server.py", line 50, in server_bind
    HTTPServer.server_bind(self)
  File "/usr/lib64/python3.9/http/server.py", line 137, in server_bind
    socketserver.TCPServer.server_bind(self)
  File "/usr/lib64/python3.9/socketserver.py", line 466, in server_bind
    self.socket.bind(self.server_address)
OSError: [Errno 98] Address already in use

Versions:

prometheus-client==0.21.0
python==3.9

Proposed fixed: Edit documentation

      to shutdown the server gracefully:

    ```python
    server, t = start_http_server(8000)
    server.shutdown()
+   server.server_close()
    t.join()
    ```

Does proposed fix work ? Yes. One can start, stop, restart prometheus server

from prometheus_client import start_http_server

server, thread = start_http_server(8000)
server.shutdown()
server.server_close()
thread.join()

server, thread = start_http_server(8000)
server.shutdown()
server.server_close()
thread.join()

server, thread = start_http_server(8000)
...

Explanation of the proposed fix: Function start_http_server returns a tuple containing 2 elements. First element is a child of WSGIServer class from wsgiref.simple_server module. We can use the standard method server_close() that closes socket connections. Note: server.shutdown() is still required even when using sever.server_close()

Tiino1 avatar Oct 28 '24 16:10 Tiino1

Are you going to update the documentation?

ethanschen avatar Feb 28 '25 17:02 ethanschen