【问题标题】:Newbie to twisted and cyclone - How to get redis callbacks to work for a simple get request新手到扭曲和旋风 - 如何让 redis 回调为简单的 get 请求工作
【发布时间】:2012-05-07 13:22:36
【问题描述】:

下面是我尝试在非阻塞方法中从 get 请求写入 redis 的代码。下面也是我得到的错误。这是一个 500 错误。我只是不明白旋风附带的 txredisapi 的文档。它确实写入了redis,但应用程序

import cyclone.web
import sys
from twisted.internet import reactor
from twisted.python import log
import cyclone.redis as redis
from twisted.internet import defer
from twisted.internet import reactor

@defer.inlineCallbacks
def redisPixelWrite(remote_ip):
    rc = yield redis.Connection()
    yield rc.set("foo", 'itwodasdfred')
    v = yield rc.get("foo")
    print "foo:", v
    yield rc.disconnect()

class Application(cyclone.web.Application):
    def __init__(self):
        handlers = [
            (r"/", MainHandler),
        ]
        settings = {"xheaders": True,"static_path": "./static"}
        cyclone.web.Application.__init__(self, handlers, **settings)       

class MainHandler(cyclone.web.RequestHandler):
    def get(self):
        remote_ip = self.request.remote_ip
        redisPixelWrite(remote_ip).addcallback()
        self.set_header('Content-Type', 'text/html')
        self.write(remote_ip)

def main():
    log.startLogging(sys.stdout)
    reactor.listenTCP(8051, Application(), interface="127.0.0.1")
    reactor.run()

if __name__ == "__main__":
    main()


2012-05-07 21:12:10+0800 [-] Log opened.
2012-05-07 21:12:10+0800 [-] Application starting on 8051
2012-05-07 21:12:10+0800 [-] Starting factory <__main__.Application instance at 0x228af38>
2012-05-07 21:12:14+0800 [HTTPConnection,0,127.0.0.1] Starting factory <cyclone.redis.RedisFactory instance at 0x261a680>
2012-05-07 21:12:14+0800 [HTTPConnection,0,127.0.0.1] Uncaught exception GET / (127.0.0.1) :: HTTPRequest(protocol='http', host='127.0.0.1:8051', method='GET', uri='/', version='HTTP/1.1', remote_ip='127.0.0.1', body='', headers={'Connection': 'keep-alive', 'Accept-Language': 'en-us,en;q=0.5', 'Accept-Encoding': 'gzip, deflate', 'Cache-Control': 'max-age=0', 'Host': '127.0.0.1:8051', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:11.0) Gecko/20100101 Firefox/11.0'})
2012-05-07 21:12:14+0800 [HTTPConnection,0,127.0.0.1] 500 GET / (127.0.0.1) 2.07ms
2012-05-07 21:12:14+0800 [RedisProtocol,client] foo: itwodasdfred
2012-05-07 21:12:14+0800 [RedisProtocol,client] Stopping factory <cyclone.redis.RedisFactory instance at 0x261a680>

【问题讨论】:

    标签: python redis twisted tornado cyclone


    【解决方案1】:

    你在代码中遗漏了一些东西。

    1. get 函数必须用inlineCallbacks 装饰,并且应该是yield redisPixelWrite(remote_ip)
    2. 您可能不想在每次请求时都与 redis 建立新连接。设置持久连接池并在新请求上重用它会更有效。

    这可能就是你要找的:

    import cyclone.redis
    import cyclone.web
    import sys
    
    from twisted.python import log
    from twisted.internet import defer
    from twisted.internet import reactor
    
    
    class RedisMixin(object):
        redis = None
    
        @classmethod
        def setup(self):
            RedisMixin.redis = cyclone.redis.lazyConnectionPool()
    
    
    class Application(cyclone.web.Application):
        def __init__(self):
            handlers = [(r"/", MainHandler)]
            RedisMixin.setup()
            settings = {"debug": True, "xheaders": True, "static_path": "./static"}
            cyclone.web.Application.__init__(self, handlers, **settings)
    
    
    class MainHandler(cyclone.web.RequestHandler, RedisMixin):
        @defer.inlineCallbacks
        def get(self):
            try:
                yield self.redis.set("foo", self.request.remote_ip)
                ip = yield self.redis.get("foo")
            except:
                raise cyclone.web.HTTPError(503)  # Service Unavailable
            else:
                self.set_header('Content-Type', 'text/html')
                self.write(ip)
    
    
    def main():
        log.startLogging(sys.stdout)
        reactor.listenTCP(8051, Application(), interface="127.0.0.1")
        reactor.run()
    
    if __name__ == "__main__":
        main()
    

    请注意,所有Connection 方法的默认行为是在redis 停止或重新启动时自动重新连接。它将以 HTTP 503(服务不可用)响应,直到重新建立连接并恢复与 redis 的通信。

    【讨论】:

      【解决方案2】:

      这一行:

      redisPixelWrite(remote_ip).addcallback()
      

      提高AttributeError。您可能应该提交一份针对 Cyclone 的错误报告,因为它应该已经在某个地方报告了这个问题(或者,确保您实际上正在查看将报告异常的日志)。

      redisPixelWrite 返回一个Deferred,因为它用inlineCallbacks 装饰。 Deferred 上没有 addcallback 方法。有一个addCallback 方法,我想这可能是您想要使用的。但是,它至少需要一个参数,而不是零,因此您还需要修复它。

      【讨论】:

        猜你喜欢
        • 2011-01-17
        • 2011-03-05
        • 1970-01-01
        • 2012-02-16
        • 2016-02-21
        • 1970-01-01
        • 1970-01-01
        • 2018-01-15
        • 2018-04-22
        相关资源
        最近更新 更多