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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions