2015-01-28 3 views
0

cherrypy가 자체의 스레드 풀을 사용한다는 것을 읽었습니다. 그러나 나는 그것의 이점을 볼 수 없습니다.CherryPy에서 동시 요청을 처리하는 방법은 무엇입니까?

오랜 시간이 걸리는 요청을 시작한 다음 다른 탭에서 짧은 시간이 걸리는 요청을 시작합니다. 실제로 멀티 스레딩을 사용하는 경우에는 짧은 요청이 긴 요청 전에 완료되어야합니다. 그러나 모든 것이 순차적으로 처리되는 것처럼 긴 요청이 완료되면 짧은 시간이 먼저 처리되는 것을보고 있습니다.

토네이도 및 twistd와 같은 다른 uWSGI 프레임 워크와 통합을 시도했지만 여전히 차이점은 없습니다. http://cherrypy.readthedocs.org/en/latest/deploy.html#tornado

이것은 내 시동 코드입니다. 누구든지 나를 도울 수 있습니까?

cfg = { 
'global' : { 
    'server.socket_host' : Utils.gflags.FLAGS.bind_addr, 
    'server.socket_port' : Utils.gflags.FLAGS.bind_port, 
    'server.thread_pool' : 10, 
    'engine.timeout_monitor.frequency' : gflags.FLAGS.request_time_out_secs, 
}, 
'/static' : {"tools.sessions.on": False, 'tools.auth.on': False}, 
'/favicon.ico' : {"tools.sessions.on": False, 'tools.auth.on': False}, 
} 

# To turn off the cherrypy errors on screen. 
cfg['global'].update({'log.screen': False}) 
cfg['/static'].update({'tools.staticdir.on': True}) 
cfg['/static'].update({'tools.staticdir.dir': Utils.gflags.FLAGS.static_dir}) 
cfg['/favicon.ico'].update({'tools.staticfile.on': True}) 
cfg['/favicon.ico'].update({'tools.staticfile.filename': 
          Utils.gflags.FLAGS.favicon_file}) 


# Disable the auto reload on code change. 
cherrypy.engine.autoreload.unsubscribe() 

# Start the cherrypy 
#Root() is defined somewhere else. Don't worry about that 
cherrypy.quickstart(Root(), config = cfg) 
+0

안녕, 는 브라우저가 두 번째 탭에서 다른 연결을 사용하여 특정 있습니까? 첫 번째 메시지를 다시 사용하기 만하면 두 메시지를 순차적으로 처리합니다. –

+0

글쎄, 당신이 말하는 것은 옳은 것 같습니다. 하지만 연결 수준이 아닌 요청 수준에서 동시성이 필요합니다. 세션을 사용하지 않도록 설정하는 것이 좋습니다. –

+0

관련 상품 http://stackoverflow.com/questions/21758014/non-blocking-concurrent-wsgi-server – jwalker

답변

1

난 당신이 정적 파일에 대한 세션 도구를 해제하는 것을 볼, 그래서 documentation related to session locking을 확인, 차단이 차단 세션에 의해 발생한다고 가정합니다.

이 예제는 설명 될 수있다 :

당신이 세션 잠금에 대한이 블로그 게시물에서 언급 한 동일한 문제가 발생하는 것처럼
"""Show the difference between explicit and implicit locking 
on the cherrypy sessions. 

To see the effects make sure your client can handle cookies, 
for example any conventional web browser or curl with 
a cookie jar. 

The exposed routes are: 

    /e/ 
    /e/block/[minutes] 
    /e/blocked_hi/ 
    /e/unblocked_hi 
    /i/ 
    /i/block/[minutes] 
    /i/blocked_hi/ 
    /i/unblocked_hi 

The application mounted on /e/ has the sessions *explicitly* locked and 
the applicaiton mounted on /i/ has the sessions *implicitly* locked. 

You can make any concurrent request on the /e branch and you 
will not have any blocking. 

If you do the requests on the following steps: 
    1. /i/ 
    2. /i/block 
    3. /i/blocked_hi 

The step 3 is going to be blocked because of the step 2, you can wait a minute 
and when the request on step 2 ends it will inmediatly complete the step 3. 
Also any request that you do to /i/unblocked_hi will respond immediately regardless 
of any blocking. 

In general if you call: 

1. /i/ or /e/ and then 
2. /i/block 
3. Any request to: 
     /i/ 
     /i/blocked_hi 
     /e/ 
    are going to be blocked in until /i/block finish. 
""" 
import time 

import cherrypy as cp 


class _App: 

    @cp.expose 
    def block(self, m=1): 
     """Sleep for `m` minutes and return.""" 
     time.sleep(float(m) * 60) 
     return "I have blocked this request {}".format(m) 

    @cp.expose 
    def blocked_hi(self): 
     """It can be blocked if the blocked method is executing, 
     the session have content and is locked. 
     """ 
     return """Hi, I could have been blocked by a session. 
     Session content: {}\n""".format(dict(cp.session)) 

    @cp.expose 
    def unblocked_hi(self): 
     return "Hi, I'm not blocked!" 


class ImplicitlyLockedApp(_App): 

    @cp.expose 
    def index(self): 
     cp.session['foo'] = 'bar' 
     return "I've just set the session content to {}".format(dict(cp.session)) 


class ExplicitlyLockedApp(_App): 

    @cp.expose 
    def index(self): 
     # This method can be blocked by /i/block because of the 
     # acquire_lock/release_lock calls. 
     cp.session.acquire_lock() 
     cp.session['foo'] = 'bar' 
     cp.session.release_lock() 
     return "I've just set the session content to {}".format(dict(cp.session)) 


if __name__ == '__main__': 
    cp.tree.mount(ImplicitlyLockedApp(), '/i', config={ 
     '/': { 
      'tools.sessions.on': True 
     }, 
     '/unblocked_hi': { # Disable the session tool to avoid any locking 
      'tools.sessions.on': False 
     } 
    }) 
    cp.tree.mount(ExplicitlyLockedApp(), '/e', config={ 
     '/': { 
      'tools.sessions.on': True, 
      'tools.sessions.locking': 'explicit' # This is the magic bit. 
     }, 
     '/unblocked_hi': { # Rather irrelevant on this case 
      'tools.sessions.on': False 
     } 
    }) 
    cp.engine.start() 
    cp.engine.block() 
+0

고마워, 세션을 비활성화하고 어떻게되는지보십시오. –

2

네, 그것은 같습니다 http://blog.schmichael.com/2007/09/20/session-locking-and-performance-in-cherrypy/

기본적으로 솔루션이 명시 적으로 잠그는 것입니다 당신의 다른 모든 요청을 차단하지 않는 코드의 다른 지점에있는 세션.

cherrypy.session.acquire_lock() 
cherrypy.session.release_lock() 
+0

감사합니다. 그것이 문제였습니다. 얼마나 미묘한 일을 그리워하고 그것이 얼마나 큰 영향을 미치는지와! –