Twisted Cyclone - How to write to redis after the request is done

302 views Asked by At

Below is my basic handler. I just want to server an image and after the requeste is complete, I want to write to redis but when I run the below code, the on_finish is not called.

import cyclone.web
import cyclone.redis 
from twisted.internet import defer
from twisted.internet import reactor
tt = cyclone.redis.lazyConnectionPool()
class PixelHandler(cyclone.web.RequestHandler):
    @cyclone.web.asynchronous
    def get(self):
        qs = qs_decode(self.request.query)
        self.set_header('Content-Type', 'image/gif')
        self.write(pixel)
        redisPixelWrite(remote_ip)
        #self.finish()
    def on_finish(self):
        t = yield tt.multi()
        yield t.set('key', 'value')
        r = yield t.commit()
        print "commit=", repr(r)
2

There are 2 answers

0
Jeethu On

on_finish will not be called unless self.finish() has been called. I'm sure you already know that. The problem in this case is that on_finish() does not support defer.inlineCallbacks (You haven't decorated your on_finish() method with it, but doing so wouldn't help).

I think rewriting on_finish() to use plain old deferreds will make this work. Try something like this:

    def on_finish(self):
        tt.multi().addCallback(
                lambda t: t.set('key', 'value').addCallback(
                    t.commit()))

A better approach would be to decorate your get() method with defer.inlineCallbacks() and move the body of on_finish() into it.

0
fiorix On

Current version of cyclone supports decorating on_finish with inlineCallbacks. Thus, fixing your code is easy:

@defer.inlineCallbacks
def on_finish(self):
    ...