Code

Opened 3 years ago

Closed 3 years ago

#16099 closed Bug (fixed)

Development web server sometimes hangs with Chrome

Reported by: jseims@… Owned by: slacy
Component: HTTP handling Version: 1.3
Severity: Normal Keywords:
Cc: slacy Triage Stage: Design decision needed
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I'm able to reproduce on the default Amazon ec2 tiny instance (Linux ip-10-112-95-131 2.6.35.11-83.9.amzn1.i686 #1 SMP Sat Feb 19 23:41:56 UTC 2011 i686 i686 i386 GNU/Linux).

If I run the dev server and hit a page with Chrome, it will often hang for exactly 60 seconds establishing a network connecting. In other words, Chrome reports the connection as "pending", and for 60 seconds nothing happens (i.e., my code doesn't run, strace doesn't say anything unusual), and then everything proceeds fine.

Behavior goes away if I use another browser, or if I run django through apache.

Let me know if I can provide additional info.

Attachments (2)

multithreaded.diff (2.2 KB) - added by slacy 3 years ago.
Patch to enable multithreaded runserver, some small doc fixes as well.
multithreaded-2.diff (791 bytes) - added by jturnbull 3 years ago.
Patch dealign only with the chrome issue, cleanly applies

Download all attachments as: .zip

Change History (16)

comment:1 Changed 3 years ago by anonymous

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

comment:2 Changed 3 years ago by aaugustin

  • Resolution set to invalid
  • Status changed from new to closed

This is a Chrome bug, acknowledged here: https://code.google.com/p/chromium-os/issues/detail?id=13043

comment:3 Changed 3 years ago by anonymous

What do you think about making the Django server multi threaded, as this comment states:

it's incredibly easy to mix multithreading into python's simple HTTP server:

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):

def init(self, server_address, HandlerClass):

HTTPServer.init(self, server_address, HandlerClass)

I made the web server in client/cros/httpd.py multithreaded in this way a few days ago.

Version 0, edited 3 years ago by anonymous (next)

comment:4 Changed 3 years ago by ShawnMilo

Probably not going to happen. From the docs:

DO NOT USE THIS SERVER IN A PRODUCTION SETTING. It has not gone through security audits or performance tests. (And that's how it's gonna stay. We're in the business of making Web frameworks, not Web servers, so improving this server to be able to handle a production environment is outside the scope of Django.)

(link: https://docs.djangoproject.com/en/1.3/ref/django-admin/)

There are plenty of other easy options, including install gunicorn and running manage.py run_gunicorn instead of runserver.

comment:5 Changed 3 years ago by anonymous

Got it.

Maybe some documentation around using the dev server? FWIW, I lost a couple days debugging this issue :(

comment:6 Changed 3 years ago by aaugustin

  • Resolution invalid deleted
  • Status changed from closed to reopened
  • Triage Stage changed from Unreviewed to Design decision needed
  • UI/UX unset

This will not be fixed in Chrome, and the problem was mentioned again in #16249. It seems that we're going to have to do something.

comment:7 Changed 3 years ago by aaugustin

  • Component changed from Uncategorized to HTTP handling
  • Type changed from Uncategorized to Bug

comment:8 Changed 3 years ago by slacy

I'm using Chrome 12.0.742.60 beta on Ubuntu 11.04 and can reproduce this easily by starting a totally blank Django project, and attempting to visit "http://localhost:8000/" using Chrome's Incognito mode.

I've looked at the strace, and the hang is right after the accept() of the new connection. The HTTP server does a recvfrom() on the new socket, and Chrome never seems to write the request.

The sequence looks like this (from "strace -T -f -o /tmp/strace.out python ./manage.py runserver --noreload": Each call is annotated with it's runtime in seconds in <>'s, so take a look at the 1st call to recvfrom() which takes 60 seconds to complete.

[...]
17271 select(4, [3], [], [], {0, 500000}) = 0 (Timeout) <0.500664>
17271 select(4, [3], [], [], {0, 500000}) = 0 (Timeout) <0.500648>
17271 select(4, [3], [], [], {0, 500000}) = 1 (in [3], left {0, 285305}) <0.214843>
17271 accept(3, {sa_family=AF_INET, sin_port=htons(49463), sin_addr=inet_addr("127.0.0.1")}, [16]) = 4 <0.000059>
17271 ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 <0.000075>
17271 recvfrom(4, "", 8192, 0, NULL, NULL) = 0 <60.004065>
17271 shutdown(4, 1 /* send */)         = 0 <0.000145>
17271 close(4)                          = 0 <0.000107>
17271 select(4, [3], [], [], {0, 500000}) = 1 (in [3], left {0, 499996}) <0.000081>
17271 accept(3, {sa_family=AF_INET, sin_port=htons(49464), sin_addr=inet_addr("127.0.0.1")}, [16]) = 4 <0.000078>
17271 ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 <0.000081>
17271 recvfrom(4, "", 8192, 0, NULL, NULL) = 0 <0.000033>
17271 shutdown(4, 1 /* send */)         = 0 <0.000099>
17271 close(4)                          = 0 <0.000027>
17271 select(4, [3], [], [], {0, 500000}) = 1 (in [3], left {0, 499997}) <0.000018>
17271 accept(3, {sa_family=AF_INET, sin_port=htons(49465), sin_addr=inet_addr("127.0.0.1")}, [16]) = 4 <0.000023>
17271 ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0 <0.000014>
17271 recvfrom(4, "GET / HTTP/1.1\r\nHost: localhost:8000\r\nConnection: keep-alive\r\nCache-Control: max-age=0\r\nUser-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.30 (KHTML, like Gecko) Chrome/12.0.742.60 Safari/534.30\r\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\nAccept-Encoding: gzip,deflate,sdch\r\nAccept-Language: en-US,en;q=0.8\r\nAccept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n\r\n", 8192, 0, NULL, NULL) = 397 <0.000022>

comment:9 Changed 3 years ago by slacy

  • Cc slacy added

This is an annoying issue for development, as it's really convenient to be logged in as your admin user in an Incognito window while you interact as a "regular" user in the non-Incognito mode.

So, not a production issue, but certainly hinders development as now I have to log in and out to switch back and forth between users (or run two instances of Chrome with different user profile directories, which is more of a hassle)

comment:10 Changed 3 years ago by slacy

Okay, after reading the Chrome bug (justifying why they're doing it) I think that adding the ThreadingMixIn might be a good idea. Shall I submit a patch?

comment:11 Changed 3 years ago by aaugustin

I still haven't seen where RFC2616 says that HTTP servers MUST accept more than 1 connection :)

Jokes asides, yes, we should probably add the ThreadingMixIn. A patch will be appreciated.

comment:12 Changed 3 years ago by slacy

  • Owner changed from nobody to slacy
  • Status changed from reopened to new

comment:13 Changed 3 years ago by slacy

  • Has patch set

Changed 3 years ago by slacy

Patch to enable multithreaded runserver, some small doc fixes as well.

Changed 3 years ago by jturnbull

Patch dealign only with the chrome issue, cleanly applies

comment:14 Changed 3 years ago by jezdez

  • Resolution set to fixed
  • Status changed from new to closed

In [16427]:

Fixed #16099 -- Enabled threading for the runserver management command and added a --nothreading option to disable it if needed. This should help Google Chrome users because it opens more than one connection speculatively.

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.