Thriftpy / thriftpy

Thriftpy has been deprecated, please migrate to https://github.com/Thriftpy/thriftpy2
MIT License
1.15k stars 286 forks source link

Running code when call finishes #249

Open pawl-rs opened 7 years ago

pawl-rs commented 7 years ago

I'm using sqlalchemy and I need to call session.remove() at the end of the call (like flask's teardown_request).

Is there a way to ensure code is run when the call is finished?

pawl-rs commented 7 years ago

I ended up overriding TProcessor for this:

class SessionTProcessor(TProcessor):
    """Modified TProcessor which runs `session.remove()` to make sure database
       connections are returned to the pool after the call.
    """
    def process(self, iprot, oprot):
        super(SessionTProcessor, self).process(iprot, oprot)

        # ensure sqlalchemy connection is returned to pool after call
        model.session.remove()
damnever commented 7 years ago

There are some other ways, for instance:

def tear_down(func):
    @wraps(func)
    def __(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        finally:
            do_sth()
    return __

class Dispatcher(object):
    @tear_down
    def handle_foo(self):
        pass
    @tear_down
    def handle_bar(self):
        pass
pawl-rs commented 7 years ago

@damnever I ended up talking to a colleague about the alternative solution, and he was concerned about "you'll have decorators everywhere" and we could potentially forget to add decorators to methods using the session. I'm thinking we're still going to end up overriding the TProcessor. Great idea though.

damnever commented 7 years ago

May someone also want to override the TServer, etc.

hit9 commented 7 years ago

Hi, this is a nice idea. Currently we are using the "decorator" way, not on the class methods but on the dispatcher class.

def do_something_around_call_context(cls):
    pass

@do_something_around_call_context
class Dispatcer(object)
    def ping(self):
        return 'pong'

By this way, every method under this dispatcher would be decorated.

Anyway, the decorator way just rewrite the target function, which is not a real hook.

cc @maralla @lxyu : How about provides some hooks like flask before_request and after_request decorators to allow developers do something like 'closes session, clear threadng locals` around the processor call context?