bottlepy / bottle

bottle.py is a fast and simple micro-framework for python web-applications.
http://bottlepy.org/
MIT License
8.39k stars 1.47k forks source link

ResourceWarning unclosed <socket.socket> #814

Open Phyks opened 8 years ago

Phyks commented 8 years ago

Hi,

When quitting a Bottle app using ^C and the built-in webserver, I get this message in the console:

/bottle.py:3119: ResourceWarning: unclosed <socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080)>

Then, it hangs, and I have to ^C a second times to exit.

It should not be a big deal, but I never saw it before. Is it due to some recent changes? Thanks!

defnull commented 8 years ago

Which Python an Bottle version?

Phyks commented 8 years ago

Python 3.5.1. Bottle 0.12.9 installed from pip.

Phyks commented 8 years ago

Let me know if I can be useful in any way :)

tprk77 commented 8 years ago

Me too! Xubuntu 16.04 x86_64, virtualenv, Python 3.5.2, Bottle 0.12.9 from pip.

katsar0v commented 7 years ago

Same here still valid

Lisias commented 7 years ago

I confirm this is still a problem.

Python 3.4.2 (default, Oct 19 2014, 13:31:11)
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import bottle
>>> bottle.__version__
'0.13-dev'
>>>

And later, after hitting CTRL-C to stop a program:

sys:1: ResourceWarning: unclosed <socket.socket fd=5, family=AddressFamily.AF_UNIX, type=2049, proto=0>
/home/srv/python/3.4/lib/python3.4/importlib/_bootstrap.py:2150: ImportWarning: sys.meta_path is empty
sys:1: ResourceWarning: unclosed <socket.socket fd=6, family=AddressFamily.AF_UNIX, type=2049, proto=0>
ahxxm commented 7 years ago

+1

python3.5.2 and 3.6.1rc1, bottle 0.12.13, paste 2.0.3

defnull commented 7 years ago

I still cannot reproduce this error. I do get the 'unclosed resource' warning, but the process does not hang.

The resource warning is caused by the stdlib wsgi server not closing the socket after a KeyboardInterrupt. It does not do much harm, since sockets are closed on process shutdown anyway, it is just annoying. Even after calling shutdown() on the server explicitly the warning remains. I don't see an easy way to prevent this warning other than patching the wsgiref server in the stdlib or waiting for a bugfix there.

gfemec commented 7 years ago

For what it's worth, fe7285893505f949b48e0f873d44c5386917b7ae (part of 0.13 development) seems to address the unclosed socket and prevents the warning for me.

robvdl commented 5 years ago

Yes but this was fixed 5 years ago (2014) and we're still waiting for it to be released which isn't very good.

You get the socket close warning on python 3 and bottle 0.12, I'm trying to port a project over to python 3 before the python 2 apocalypse sets in :) but bottle 0.13 is still in dev, can't this fix be backported to 0.12?

p0lm commented 4 years ago

Still bumping into this.

chrism commented 4 years ago

Getting this message too.

If anyone knows of a workaround much appreciated.

sbargy commented 4 years ago

Yep, I'm getting this warning, too. Hadn't seen it before, just cropped up in the last couple days. I'm investigating further to see what changed.

robvdl commented 4 years ago

@sbargy interesting I always thought it was running on Python 3 that did this. Have you always been on python3 or have you only recently upgraded to python3?

franz-simonetti commented 4 years ago

Very similar problem: when quitting a Bottle app using ^C and the built-in webserver, I get this message in the console: sys:1: ResourceWarning: unclosed <socket.socket fd=544, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080)> ResourceWarning: Enable tracemalloc to get the object allocation traceback However it does not hangs, I get the command prompt directly. Python 3.8.2, Bottle v0.12.18 on Windows 10 Pro 1909 build 18363.778

Nozavi commented 4 years ago

Experiencing the same issue Python 3.7, Bottle v0.12.18, Windows 10 Pro 1909 build 18363.836

bottle.py:3139: ResourceWarning: unclosed <socket.socket fd=752, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080)>

sbargy commented 4 years ago

@robvdl I've been running Python 3 on this code base since it was started.

robvdl commented 4 years ago

Ok it might not just be Python 3 but be something we're doing but it's irrelevant because it's happening to a LOT of people, not just me and it's not getting resolved by backporting the 0.13 fix (it should be). Bottle.py releases come out at a snails pace we've been waiting for about 5 years for 0.13, I'm trying to not be negative but it's hard, how long until 0.13 is not in beta? it's getting a bit rediculous.

Our codebase did not come up with the unclosed socket error on Python 2, but did do it on Python 3 which made me conclude it was that at the time.

The only reason we are still using bottle.py is because we're stuck with it on a legacy project, but the bottle release procedure is really slow. Bottle 0.12 came out in 2014 it's now 6 years later and 0.13 is still not out.

robvdl commented 4 years ago

@sbargy did you try it with autoreloading (hot reload) that triggers it. Make a code change, bottle restarts and says unclosed socket.

x-yuri commented 4 years ago

Debian 10 "buster", Python 3.8.3, bottle==0.12.18. It doesn't hang. The warning is only displayed in debug mode. #648 resolves the issue (for wsgiref):

--- /usr/local/bin/bottle.py    2020-07-05 12:40:20.499112052 +0000
+++ /usr/local/bin/bottle.py    2020-07-05 12:40:44.522967162 +0000
@@ -2787,7 +2787,11 @@
                     address_family = socket.AF_INET6

         srv = make_server(self.host, self.port, app, server_cls, handler_cls)
-        srv.serve_forever()
+        try:
+            srv.serve_forever()
+        except KeyboardInterrupt:
+            srv.server_close() # Prevent ResourceWarning: unclosed socket
+            raise

 class CherryPyServer(ServerAdapter):

Although the documentation recommends:

Creating a server requires several steps. First, you must create a request handler class by subclassing the BaseRequestHandler class and overriding its handle() method; this method will process incoming requests. Second, you must instantiate one of the server classes, passing it the server’s address and the request handler class. It is recommended to use the server in a with statement. Then call the handle_request() or serve_forever() method of the server object to process one or many requests. Finally, call server_close() to close the socket (unless you used a with statement).

So supposedly not a wsgiref issue.

Then, it hangs

Are you sure? Maybe just outputs the warning over the prompt?

More on it here.

satisfaya commented 3 years ago

GUYS! This problem is nothing to worry about. Make these changes to fix the problem: from bottle import Bottle then set app = Bottle() finally change the run command to: run(app, host='localhost', port=8080)

qcda1 commented 1 year ago

Humm. I still have this message and I would need to know how to close the socket when the program exit the run statement. In my case, I would like to restart the web server (run statement) by sending SIGINT to the running process. By doing this, the program bomb when run is launch again as follow:

Here is the terminal session: daniel@MPDeb64:~/devel/midnite$ python 'midnitenp (copie).py' Step Start of program, duration=0.00ms Step run(host... statement, duration=0.06ms Bottle v0.12.19 server starting up (using WSGIRefServer())... Listening on http://localhost:8080/ Hit Ctrl-C to quit.

127.0.0.1 - - [17/Jan/2023 11:31:47] "GET /mesures1 HTTP/1.1" 404 736 OK received SIGINT and exited from run, waiting 10 seconds... Step Start of program, duration=0.01ms Step run(host... statement, duration=0.08ms Bottle v0.12.19 server starting up (using WSGIRefServer())... Listening on http://localhost:8080/ Hit Ctrl-C to quit.

Traceback (most recent call last): File "midnitenp (copie).py", line 113, in run(app, host='localhost', port=8080) File "/home/daniel/.local/lib/python3.7/site-packages/bottle.py", line 3137, in run server.run(app) File "/home/daniel/.local/lib/python3.7/site-packages/bottle.py", line 2789, in run srv = make_server(self.host, self.port, app, server_cls, handler_cls) File "/usr/lib/python3.7/wsgiref/simple_server.py", line 153, in make_server server = server_class((host, port), handler_class) File "/usr/lib/python3.7/socketserver.py", line 452, in init self.server_bind() File "/usr/lib/python3.7/wsgiref/simple_server.py", line 50, in server_bind HTTPServer.server_bind(self) File "/usr/lib/python3.7/http/server.py", line 137, in server_bind socketserver.TCPServer.server_bind(self) File "/usr/lib/python3.7/socketserver.py", line 466, in server_bind self.socket.bind(self.server_address) OSError: [Errno 98] Address already in use /usr/local/lib/python3.7/dist-packages/matplotlib/_pylab_helpers.py:92: ResourceWarning: unclosed <socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 8080)> gc.collect(1) ResourceWarning: Enable tracemalloc to get the object allocation traceback daniel@MPDeb64:~/devel/midnite$

Here is the code:

MAIN PROGRAM

while True: ts = time.time() stamp("Start of program")
stamp("run(host... statement") app = Bottle() debug(True) run(app, host='localhost', port=8080) print("OK received SIGINT and exited from run, waiting 10 seconds...") sleep(10)

print("Program end.")

Thanks for the help! Regards, Daniel.

defnull commented 1 year ago

This is fixed in master, but not in 0.12 yet. The wsgitef implementation does not properly clean up the socket server on SIGINT, so you could use a different server adapter that handles interrupts better, or skip the server adapter and the run() method and instead setup wsgiref.simple_server yourself. Bottles server-adapters are only a suggestion, you can simply run Bottle with wsgiref as suggested by https://github.com/bottlepy/bottle/issues/814#issuecomment-653884603

qcda1 commented 1 year ago

Thanks very much. Couldn't see the workarounds you mentioned. Will wait next version and will try letting the Python program end at SIGINT and have a calling Bash script relaunch.