Opened 10 years ago
Closed 10 years ago
#24398 closed Bug (needsinfo)
Built in webserver not reloading Python files upon requests
Reported by: | Zsolt Ero | Owned by: | nobody |
---|---|---|---|
Component: | Uncategorized | Version: | 1.7 |
Severity: | Normal | Keywords: | server runserver |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
I am experiencing the following bug in Django 1.7.4:
- Create a new default project
- Create a new default app.
- Make a view + url, just return a simple string in a HttpResponse.
- Start "manage.py runserver"
- Load the URL in browser / curl.
- Change string in the view.
- Reload the URL in browser / re-run curl.
What should happen:
The updated contents should be shown in the browser / curl.
What is happening:
Sometimes the updated content is displayed.
Most of the time the old content is displayed.
Note 1:
If I wait a while (say 5 minutes), and reload, the updated content will be displayed.
If I do not wait, but simply click reload-reload-reload, the old content will be displayed all the time.
Note 2:
If I hit the force-reload button in the browser (by clicking Ctrl + refresh or similar), then it triggers a server reload/restart. However the result of this response is still the old content. However if I do a normal request now (so it's the 2nd request after reload), then the updated content is displayed.
Note 3:
A very interesting, possibly related bug: if I hit Ctrl + C to quit the server and restart it, it terminates with error"
Error: That port is already in use.
To be able to restart the server I have to wait quite a while (say 20 seconds). This error seems to only happen when the server is in the "stuck" mode, as in displaying the old content.
Python version: 2.7.9, latest from homebrew
Django version: 1.7.4, latest from pip
OS version: OS X 10.9.5
Change History (15)
comment:1 by , 10 years ago
Description: | modified (diff) |
---|
comment:2 by , 10 years ago
Description: | modified (diff) |
---|
comment:3 by , 10 years ago
follow-up: 5 comment:4 by , 10 years ago
It seems like you might have some kind of orphaned or zombie runserver process running in the background and interfering with things. Can you try restarting your computer, running ps wuax | grep runserver
to ensure there are no runserver processes running, then start runserver (just once) and see if you can still reproduce these issues?
comment:5 by , 10 years ago
Even before restarting the computer, there isn't any process for "ps wuax | grep runserver", except for the grep one. I'll try restarting now.
comment:6 by , 10 years ago
Have you ever started any other kind of server that might be serving on the same port? Gunicorn, uWSGI, Apache...?
comment:7 by , 10 years ago
Same behaviour after restart.
- No change upon reloading. Tried it for long time.
- Port error after quitting the server.
- Had to wait 15 seconds (tested by re-running the last command every second), till it allowed actually running the server.
comment:8 by , 10 years ago
- No other webserver installed on the system.
- Zombie process confirmed, when in "stuck" state, the ps wuax displays the process in the list.
- After quitting the server and back in terminal, the following warning message appears out of nowhere when the zombie process terminates in the background.
Exception KeyboardInterrupt in <module 'threading' from '/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.pyc'> ignored
comment:9 by , 10 years ago
Needs documentation: | set |
---|---|
Needs tests: | set |
Patch needs improvement: | set |
comment:10 by , 10 years ago
Needs documentation: | unset |
---|---|
Needs tests: | unset |
Patch needs improvement: | unset |
We usually don't set any of those flags unless the ticket has a patch to begin with.
I'm afraid the only way this ticket is likely to be solved is if someone who can reproduce it tracks down the root cause - and right now the known set of people who can reproduce it includes only yourself :/ Clearly runserver is not behaving correctly on your system, but at this point it's impossible to say whether it's a bug in runserver or something else about your system.
You could experiment with the --noreload
and --nothreading
options to see how they change the behavior. (Obviously with --noreload
it's expected for the server to never auto-reload on changes to .py
files, but it might be interesting to know if this changes the shutdown issue you're seeing.)
comment:11 by , 10 years ago
I'm sure there'll be other developers with OS X 10.9.5 and Python 2.7.9.
Difference with --noreload:
No zombie process, but the whole server waits after Ctrl+C for quite a while. Like 15 seconds. It'd be interesting to know what is it waiting for. Also, no "Exception KeyboardInterrupt" this way.
--nothreading:
- This fixed all the problems!
- Behaves very differently then normal mode: if I save a file, which was already loaded, the server is triggered into an auto reload, simply on saving the file
- In the threading mode, the auto reload was not triggered like this.
--nothreading --noreload:
Upon Ctrl + C, I couldn't quit the server, but received this:
^C---------------------------------------- Exception happened during processing of request from ('127.0.0.1', 50457) Traceback (most recent call last): File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 295, in _handle_request_noblock self.process_request(request, client_address) File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 321, in process_request self.finish_request(request, client_address) File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 334, in finish_request self.RequestHandlerClass(request, client_address, self) File "/Users/user/Dropbox/sync/dev/django/tango/venv/lib/python2.7/site-packages/django/core/servers/basehttp.py", line 129, in __init__ super(WSGIRequestHandler, self).__init__(*args, **kwargs) File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/SocketServer.py", line 655, in __init__ self.handle() File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/wsgiref/simple_server.py", line 116, in handle self.raw_requestline = self.rfile.readline(65537) File "/usr/local/Cellar/python/2.7.9/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 476, in readline data = self._sock.recv(self._rbufsize) KeyboardInterrupt ----------------------------------------
comment:12 by , 10 years ago
The behavior you describe with --nothreading
(where the server reloads immediately upon a file save) is the normal and expected behavior. So something is broken on your system with the runserver threading.
I am sure there are other developers using the same OS X and Python versions, but I doubt they will all be able to reproduce this behavior (or else I think we'd have had many reports much earlier; runserver has had threading for several years). But hopefully someone can reproduce - we'll see!
comment:13 by , 10 years ago
Recreated the whole thing from scratch, both in 1.7.4, 1.7.0 and 1.6.10.
Result: bug only in 1.7.x.
Put it into two repos:
https://github.com/hyperknot/django_threading_bug_17
https://github.com/hyperknot/django_threading_bug_16
comment:14 by , 10 years ago
If you could start with the stable/1.7.x branch and use git bisect to bisect the commit where the change happened, that might give some insight. Follow those instructions, but mark commits good or bad manually after you test instead of using git bisect run
.
comment:15 by , 10 years ago
Resolution: | → needsinfo |
---|---|
Status: | new → closed |
Sorry, it seems while I did an edit someone added these, but by clicking update I removed these 3 from the ticket:
Needs documentation unset
Needs tests unset
Patch needs improvement unset