Python twisted和cyclone的新手-如何让redis回调为一个简单的get请求工作

Python twisted和cyclone的新手-如何让redis回调为一个简单的get请求工作,python,redis,twisted,tornado,cyclone,Python,Redis,Twisted,Tornado,Cyclone,下面是我的代码,用于尝试使用非阻塞方法从get请求写入redis。下面是我得到的错误。这是一个500的错误。我只是不明白cyclone附带的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

下面是我的代码,用于尝试使用非阻塞方法从get请求写入redis。下面是我得到的错误。这是一个500的错误。我只是不明白cyclone附带的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>
import cyclone.web
导入系统
从twisted.internet导入
从twisted.python导入日志
将cyclone.redis导入为redis
从twisted.internet导入延迟
从twisted.internet导入
@defer.inlineCallbacks
def重新像素写入(远程ip):
rc=收益率redis.Connection()
收益率rc.set(“foo”,“itwodasdfred”)
v=收益率rc.get(“foo”)
打印“foo:”,v
屈服rc.disconnect()
类应用程序(cyclone.web.Application):
定义初始化(自):
处理程序=[
(r“/”,主处理器),
]
设置={“xheaders”:True,“静态路径”:“/static”}
cyclone.web.Application.\uuuuu init\uuuuuuu(self,handlers,**设置)
类MainHandler(cyclone.web.RequestHandler):
def get(自我):
远程ip=self.request.remote\u ip
redisPixelWrite(远程ip).addcallback()
self.set_标题('Content-Type','text/html'))
自写(远程ip)
def main():
日志记录(sys.stdout)
reactor.listenTCP(8051,Application(),interface=“127.0.0.1”)
反应堆运行()
如果名称=“\uuuuu main\uuuuuuuu”:
main()
2012-05-07 21:12:10+0800[-]日志已打开。
2012-05-07 21:12:10+0800[-]申请从8051开始
2012-05-07 21:12:10+0800[-]启动工厂
2012-05-07 21:12:14+0800[HTTPConnection,0127.0.0.1]启动工厂
2012-05-07 21:12:14+0800[HTTPConnection,0127.0.0.1]未捕获的异常获取/(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;rv:11.0)Gecko/20100101 Firefox/11.0'})
2012-05-07 21:12:14+0800[HTTPConnection,0127.0.0.1]500 GET/(127.0.0.1)2.07ms
2012-05-07 21:12:14+0800[再贴现协议,客户]foo:itwodasdfred
2012-05-07 21:12:14+0800[协议,客户]停止工厂
此行:

redisPixelWrite(remote_ip).addcallback()
提高
AttributeError
。您可能应该针对Cyclone提交一份bug报告,因为它应该在某个地方报告这一点(或者,确保您实际上正在查看将报告异常的日志)


redisPixelWrite
返回一个
Deferred
,因为它用
inlineCallbacks
修饰。在
Deferred
上没有
addcallback
方法。有一个
addcallback
方法,我想这可能是您想要使用的。它至少需要一个参数,而不是零,所以您不需要您还需要解决这个问题。

您在代码中遗漏了一些内容

  • get
    函数必须用
    inlineCallbacks
    修饰,并且它应该
    产生redisPixelWrite(远程ip)
  • 您可能不想在每次请求时都与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()
    
    请注意,所有
    连接方法的默认行为都是在redis停止或重新启动时自动重新连接。它将使用HTTP 503(服务不可用)进行响应,直到重新建立连接并恢复与redis的通信