question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Long polling cripples cherrypy

See original GitHub issue

Originally reported by: shapeshifter (Bitbucket: shapeshifter, GitHub: @shapeshifter)


I’m having trouble making long polling work correctly with cherrypy:

Here’s a test case. There’s a boolean “self.done” which can be switched using “/set_done” and “/set_pending”. While it’s False, “/long_poll” will be kept open and when calling “/set_done”, it will return a response saying “Done!”.

The problem is: When calling long_poll a couple of times (about 5-10), the server becomes very unresponsive. The problem is even more distinct when killing the long_poll connections from the client. In that case, the server becomes completely unresponsive. This happens even though I’ve set the thread pool limit to -1.

cherrypy_config:

[global]
tree.test = test.app
server.socket_host = '0.0.0.0'
server.socket_port = 8090
server.thread_pool_max = -1
tools.encode.encoding = 'utf-8'
tools.encode.on = True 
log.error_file = "/tmp/cp_errors.log"

[/]
tools.sessions.on = False

test.py:

#!/usr/bin/python2
# -*- coding: utf-8 -*-

import time
import cherrypy

class Test(object):
    def __init__(self):
        self.done = False

    @cherrypy.expose
    def long_poll(self):
        cherrypy.response.timeout = 7200
        while True:
            if self.done == False:
                time.sleep(0.5)
            else:
                return "Done!\n"

    @cherrypy.expose
    def set_done(self):
        self.done = True
        return "set done\n"

    @cherrypy.expose
    def set_pending(self):
        self.done = False
        return "set pending\n"

    @cherrypy.expose
    def test(self):
        return "still working OK\n"

app = cherrypy.Application(Test())

Here’s a sample run using just wget.

Start the server:

[straydog@saskatoon testcase]$ cherryd -c cherrypy_config
[07/Jan/2012:15:16:25] ENGINE Mounted: cherrypy._cptree.Application(<test.Test object at 0x96b6d8c>, '') on /
[07/Jan/2012:15:16:25] ENGINE Listening for SIGHUP.
[07/Jan/2012:15:16:25] ENGINE Listening for SIGTERM.
[07/Jan/2012:15:16:25] ENGINE Listening for SIGUSR1.
[07/Jan/2012:15:16:25] ENGINE Bus STARTING
[07/Jan/2012:15:16:25] ENGINE Started monitor thread '_TimeoutMonitor'.
[07/Jan/2012:15:16:25] ENGINE Started monitor thread 'Autoreloader'.
[07/Jan/2012:15:16:25] ENGINE Serving on 0.0.0.0:8090
[07/Jan/2012:15:16:25] ENGINE Bus STARTED

Initial test:

[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/test -O -
still working OK

Start one long_poll in the background to demo the functionality and then call set_done. Everything works as expected:

[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[1] 1794
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/set_done -O -
set done
[shapeshifter@bluerabbit cherrypylongpolltest]$ Done!

[1]+  Done                    wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O -

Set pending again, and then open several long_poll connections in background:

[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/set_pending -O -
set pending
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/test -O -
still working OK
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[1] 1798
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[2] 1799
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[3] 1800
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[4] 1801
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[5] 1802
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[6] 1803
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[7] 1804
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[8] 1805
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[9] 1806
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[10] 1807
[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/long_poll -O - &
[11] 1808

Now calling even just “test” which should just return a message hangs forever:

[shapeshifter@bluerabbit cherrypylongpolltest]$ wget -q http://saskatoon.icu.uzh.ch:8090/test -O -
#not working anymore!

At this point, even “killall wget” doesn’t help and if anything, makes the problem worse.

I have no idea how to remedy this or if this behavior is to be expected but with a -1 thread pool, I’d guess that cherrypy should always be able to answer requests, even with several open connections.


Issue Analytics

  • State:open
  • Created 12 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
jaracocommented, Jul 29, 2016

See cherrypy-dynpool for a project that implements a dynamic thread pool. Contributions to improve the implementation or have the documentation match the implementation are also welcome.

0reactions
clawsooncommented, Dec 14, 2016

@webknjaz I’m not sure if I’m smart enough. 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Advanced — CherryPy 18.6.1.dev49+g98929b51.d20210117 ...
Various hacks had been proposed such as Comet, polling, etc. WebSocket is a socket that starts its life from a HTTP upgrade request....
Read more >
Does CherryPy support long-polling enabled paths in its ...
My use case is like this: The frontend will request long-polling to the backend to see if there is any new members update....
Read more >
CherryPy Documentation - Read the Docs
1. Simplicity. Developing with CherryPy is a simple task. “Hello, world” is only a few lines long, and does not require the.
Read more >
CherryPy Documentation
“Hello, world” is only a few lines long, and does not require the ... Various hacks had been proposed such as Comet, polling,...
Read more >
Cherrypy, handling the client's disconnected during the long polling ...
Handling the client's disconnected during the long polling. When the web page is reloaded, the browser is aborting the connection. But the cherrypy...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found