redis-limpyd icon indicating copy to clipboard operation
redis-limpyd copied to clipboard

Add middlewares management

Open twidi opened this issue 12 years ago • 2 comments

The goal of this middleware system is to add an entry point to help enhance the limpyd behavior without touching its core.

A middleware is a class which surround a redis call when a command n a field is called.

The pre_command method of each middleware, is called before the redis call, then the post_command method of each middleware in reverse order.

If a pre_command method returns something (not None), the redis call won't be done and the result value will be used instead (and other pre_command methods won't be called too).

A post_command method must return a Result object, which contains the value got from redis (or from a pre_command method).

A pre_command method accepts two arguments:

  • command, a Command object, with three fields (name (of the command) and args and kwargs to pass to the command)
  • context, a dict initialized with a sender entry, which is the object on which the original command apply (a field or a model)

The command object can be modified if wanted, before used to call redis. The context dict can also be modified, to add properties useful to the middleware that it would need in the post_command for example. Note that each called middleware share the same context dictionary.

A post_command method accepts three arguments:

  • command, the Command object passed through the pre_command methods
  • result, a Result object with a single field, value, which hold the result of the redis call
  • context, the same dictionary passed through the pre_command methods.

The result can be modified, and it's value returned from the last post_command metho will be used as a result to the call. (The command and context objects can still be modified, but it is not really useful)

To define a new middleware, simply inherit from BaseMiddleware in limpyd.middlewares and define a pre_command and/or a post_command (they are both optional, only the existing methods will be used).

To use middlewares, you must declare it when creating your database:

database = RedisDatabase(
    middlewares=[
            AMiddleware(with_some=params),
            AnotherMiddleware(),
        ], 
    **my_connection_settings
)

An example (but usable) middleware is provided in limpyd.middlewares, to log commands, their results (optional) and the duration (optional too): LoggingMiddleware. It can log stuff like:

[#1] Command(name='set', args=(u'mynamespace:mymodel:1:myfield', 'foo'), kwargs={})"
[#1, in 321µs] Result(value=1)

twidi avatar Jan 16 '13 00:01 twidi

Missing docs, but what about using my loooong PR description ?

twidi avatar Jan 16 '13 00:01 twidi

Yes, for the doc :) Just add a field in doc/ and point to it in index.rst.

yohanboniface avatar Jan 16 '13 10:01 yohanboniface