Skip to content

Fix server shutdown #1068

@Tiino1

Description

@Tiino1

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()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions