扭曲和旋风的新手 - 如何让redis回调为简单的get请求工作

时间:2012-05-07 13:22:36

标签: python redis twisted tornado cyclone

下面是我的代码,用于尝试从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>

2 个答案:

答案 0 :(得分:2)

你错过了代码中的一些内容。

  1. get函数必须使用inlineCallbacks进行修饰,并yield redisPixelWrite(remote_ip)
  2. 您可能不希望在每个请求上建立与redis的新连接。设置持久连接池并在新请求上重用它会更有效。
  3. 这可能就是你要找的东西:

    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的通信。

答案 1 :(得分:1)

这一行:

redisPixelWrite(remote_ip).addcallback()

加注AttributeError。您应该提交针对Cyclone的错误报告,因为它应该在某处报告此情况(或者,确保您实际上正在查看将报告异常的日志)。

redisPixelWrite会返回Deferred,因为它是用inlineCallbacks修饰的。 addcallback上没有Deferred方法。有addCallback方法,我想这可能就是你想要使用的方法。它至少需要一个参数,而不是零,所以你也需要修复它。