Previously non-blocking commands were getting connection from connectionQueue and then immediately putting it back. Due to nature of DeferredQueue this caused all pending queries to be processed recursively. Recursion might be extremely deep if there are many queries waiting for connection to be ready.
Proposed solution is to support peeking connection from connectionQueue without removing it from one for non-blocking commands. This is implemented by subclassing DeferredQueue. When connection is ready (put into connectionQueue) and many queries are waiting for it, all of them will be processed in a loop instead of recursion.
All blocking commands are now marked by release_on_callback flag which is True for commands that should release connection when response is received (blpop, brpop, brpoplpush) and False for commands that still block connection even after response is received (mutli, watch, pipeline). This helps to make ConnectionHandler.__getattr__ more clean by removing complex conditionals.
This is a solution for #106
Previously non-blocking commands were getting connection from
connectionQueue
and then immediately putting it back. Due to nature ofDeferredQueue
this caused all pending queries to be processed recursively. Recursion might be extremely deep if there are many queries waiting for connection to be ready.Proposed solution is to support peeking connection from
connectionQueue
without removing it from one for non-blocking commands. This is implemented by subclassingDeferredQueue
. When connection is ready (put intoconnectionQueue
) and many queries are waiting for it, all of them will be processed in a loop instead of recursion.All blocking commands are now marked by
release_on_callback
flag which isTrue
for commands that should release connection when response is received (blpop
,brpop
,brpoplpush
) andFalse
for commands that still block connection even after response is received (mutli
,watch
,pipeline
). This helps to makeConnectionHandler.__getattr__
more clean by removing complex conditionals.