Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Long polling connection kept open by Firefox after response #2

Open
theJenix opened this issue Feb 10, 2014 · 4 comments
Open

Long polling connection kept open by Firefox after response #2

theJenix opened this issue Feb 10, 2014 · 4 comments

Comments

@theJenix
Copy link

The gevent server keeps connections open for HTTP/1.1 requests, which will cause other connections to block.

To illustrate this issue, I configured gevent to use a pool of 1 greenlet. I accessed my long polling URL with Firefox, and observed the operation time out correctly. I then attempt to access the URL with wget, and it blocked until I quit Firefox or killed the server. This can be fixed by setting the 'Connection' response attribute to 'close', like this:

def dispatch(self, request, *args, **kwargs):
    response = BaseLongPollingView.dispatch(self, request, *args, **kwargs)
    response['Connection'] = 'close'
    return response

Can you add a variable into BaseLongPollingView that, if true, will automatically add this attribute to the response?

@tbarbugli
Copy link
Owner

Can you add more information about how to reproduce this issue?

2014-02-10 Jesse Rosalia [email protected]:

The gevent server keeps connections open for HTTP/1.1 requests, which will
cause other connections to block.

To illustrate this issue, I configured gevent to use a pool of 1 greenlet.
I accessed my long polling URL with Firefox, and observed the operation
time out correctly. I then attempt to access the URL with wget, and it
blocked until I quit Firefox or killed the server. This can be fixed by
setting the 'Connection' response attribute to 'close', like this:

def dispatch(self, request, _args, *_kwargs):
response = BaseLongPollingView.dispatch(self, request, _args, *_kwargs)
response['Connection'] = 'close'
return response

Can you add a variable into BaseLongPollingView that, if true, will
automatically add this attribute to the response?

Reply to this email directly or view it on GitHubhttps://github.com//issues/2
.

@theJenix
Copy link
Author

Sure. I am using Django 1.6.1, gevent 1.0, django_longpolling 0.1.2, and the django-gevent-deploy app (https://github.com/miki725/django-gevent-deploy) with a simple Django app. I add GEVENT_POOL_SIZE=1 to my settings.py file, and add the long polling example from this project's readme to my views.py:

class CountTenView(BaseLongPollingView):
    def iterator(self):
        sleep(42)
        yield '42!'

and urls.py:

url(r'^/count_ten/$', CountTenView.as_view(timeout=10))

I then start my server using:

python manage.py rungevent

and browsed to http://localhost:8000/count_ten with Firefox. It timed out after 10 seconds. I then attempted to wget that url, and it blocked until I closed Firefox. I then restarted the server, and ran the same test starting with wget. wget was able to succeed, and then Firefox was able to succeed, but after Firefox issued it's request, wget was blocked indefinitely.

@tbarbugli
Copy link
Owner

thats interesting, I never used the django gevent deploy; mainly because I
am very happy with gunicorn feature/simplicity trade off.
Could you try to run your app with gunicorn and do the same test? (I cant
reproduce it)

running the app with gunicorn should just a matter of

pip install gunicorn
gunicorn -k gevent wsgi -w 1 (assuming wsgi is a python module containing
an instance of your app)

2014-02-10 Jesse Rosalia [email protected]:

Sure. I am using Django 1.6.1, gevent 1.0, django_longpolling 0.1.2, and
the django-gevent-deploy app (
https://github.com/miki725/django-gevent-deploy) with a simple Django
app. I add GEVENT_POOL_SIZE=1 to my settings.py file, and add the long
polling example from this project's readme to my views.py:

class CountTenView(BaseLongPollingView):
def iterator(self):
sleep(42)
yield '42!'

and urls.py:

url(r'^/count_ten/$', CountTenView.as_view(timeout=10))

I then start my server using:

python manage.py rungevent

and browsed to http://localhost:8000/count_ten with Firefox. It timed out
after 10 seconds. I then attempted to wget that url, and it blocked until I
closed Firefox. I then restarted the server, and ran the same test starting
with wget. wget was able to succeed, and then Firefox was able to succeed,
but after Firefox issued it's request, wget was blocked indefinitely.

Reply to this email directly or view it on GitHubhttps://github.com//issues/2#issuecomment-34664931
.

@theJenix
Copy link
Author

This has been on my list to follow up on for like two years. I finally got around to running this with gunicorn and cannot reproduce the original issue. I think this may be because the GEVENT_POOL_SIZE and gunicorn worker parameters mean different things. As an additional test, I added in the response header to close the connection (from above) and ran python manage.py rungevent. I then issued a query using wget and Firefox simultaneously. One of the queries took twice as long to time out than the other, suggesting that they are serialized through that one Greenlet. In either case, sorry for the massive delay in getting back to you. I think you can close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants