tbarbugli / django_longpolling

django longpolling request implementation
BSD 3-Clause "New" or "Revised" License
37 stars 9 forks source link

Long polling connection kept open by Firefox after response #2

Open theJenix opened 10 years ago

theJenix commented 10 years ago

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 commented 10 years ago

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

2014-02-10 Jesse Rosalia notifications@github.com:

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/tbarbugli/django_longpolling/issues/2 .

theJenix commented 10 years ago

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 commented 10 years ago

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 notifications@github.com:

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/tbarbugli/django_longpolling/issues/2#issuecomment-34664931 .

theJenix commented 8 years ago

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.