Reputation: 9333
from http.server import HTTPServer, SimpleHTTPRequestHandler
import threading
with HTTPServer(("localhost", 8080), SimpleHTTPRequestHandler) as httpd:
threading.Thread(target=httpd.serve_forever, daemon=True).start()
# Do something ...
When the program exits the with
block, is it guaranteed that httpd
is closed properly? For example, if httpd
is transmitting data when the code reaches the end of the with
block, would that connection be properly cut off (or being waited for until it finishes)?
My understanding is that ThreadingHTTPServer
should be handling these properly, because the doc says:
socketserver.ThreadingMixIn.server_close()
waits until all non-daemon threads complete, except ifsocketserver.ThreadingMixIn.block_on_close
attribute is false. Use daemonic threads by settingThreadingMixIn.daemon_threads
to True to not wait until threads complete.
But I would like to see whether Python's most basic built-in http server HTTPServer
would also handle this properly.
Upvotes: 0
Views: 601
Reputation: 7886
http.server.HTTPServer
is a subclass of socketserver.TCPServer
is a subclass of socketserver.BaseServer
. In BaseServer
.serve_forever
is defined. Here it is made appearnt that the correct way to shutdown .serve_forever
in a different thread is to call .shutdown()
. This is what you should be doing before the with
statement ends.
Now to the question you ask: What would serve_forever
do when you don't call .shutdown()
? Well, I am not sure. The __exit__
function only closes the socket, it doesn't do any cleanup. The answer appears to be 'Whatever your OSes implementation of select.select
does when it has no sockets to select over.' What this is? Apparently, on Unix just continue like nothing happened, on Windows raise an exception? This would means on Unix the server would just continue to serve forever, while on Windows it will raise an exception. (Note that I am not sure about this. Just .shutdown()
)
Upvotes: 1