diff options
author | andy <andy@whiskeymedia.com> | 2011-07-17 15:05:58 -0700 |
---|---|---|
committer | andy <andy@whiskeymedia.com> | 2011-07-17 15:05:58 -0700 |
commit | 2d428eca210154d07ab4260fdb1cccf14954295e (patch) | |
tree | 5ea8877e3b03b9b420c27790141cf04dfcb220b3 | |
parent | c9daf07bb67696263118a17b0359fafa7ac27c53 (diff) | |
parent | deffb957bbd3b5f83eecfd025989f8086934cd30 (diff) | |
download | redis-py-2d428eca210154d07ab4260fdb1cccf14954295e.tar.gz |
Merge remote-tracking branch 'wolever/pipeline-context-manager'
-rw-r--r-- | README.md | 61 |
1 files changed, 40 insertions, 21 deletions
@@ -174,29 +174,48 @@ execution of that transaction, the entre transaction will be canceled and a WatchError will be raised. To implement our own client-side INCR command, we could do something like this: + >>> with r.pipeline() as pipe: + ... while 1: + ... try: + ... # put a WATCH on the key that holds our sequence value + ... pipe.watch('OUR-SEQUENCE-KEY') + ... # after WATCHing, the pipeline is put into immediate execution + ... # mode until we tell it to start buffering commands again. + ... # this allows us to get the current value of our sequence + ... current_value = pipe.get('OUR-SEQUENCE-KEY') + ... next_value = int(current_value) + 1 + ... # now we can put the pipeline back into buffered mode with MULTI + ... pipe.multi() + ... pipe.set('OUR-SEQUENCE-KEY', next_value) + ... # and finally, execute the pipeline (the set command) + ... pipe.execute() + ... # if a WatchError wasn't raised during execution, everything + ... # we just did happened atomically. + ... break + ... except WatchError: + ... # another client must have changed 'OUR-SEQUENCE-KEY' between + ... # the time we started WATCHing it and the pipeline's execution. + ... # our best bet is to just retry. + ... continue + +Note that, because the `Pipeline` must bind to a single connection for the +duration of a `watch`, care must be taken to ensure that he connection is +returned to the connection pool by calling the `reset()` method. If the +`Pipeline` is used as a context manager (as in the example above) `reset()` +will be called automatically... But it can also be called manually, like this: + >>> pipe = r.pipeline() >>> while 1: - >>> try: - >>> # put a WATCH on the key that holds our sequence value - >>> pipe.watch('OUR-SEQUENCE-KEY') - >>> # after WATCHing, the pipeline is put into immediate execution - >>> # mode until we tell it to start buffering commands again. - >>> # this allows us to get the current value of our sequence - >>> current_value = pipe.get('OUR-SEQUENCE-KEY') - >>> next_value = int(current_value) + 1 - >>> # now we can put the pipeline back into buffered mode with MULTI - >>> pipe.multi() - >>> pipe.set('OUR-SEQUENCE-KEY', next_value) - >>> # and finally, execute the pipeline (the set command) - >>> pipe.execute() - >>> # if a WatchError wasn't raised during execution, everything - >>> # we just did happened atomically. - >>> break - >>> except WatchError: - >>> # another client must have changed 'OUR-SEQUENCE-KEY' between - >>> # the time we started WATCHing it and the pipeline's execution. - >>> # our best bet is to just retry. - >>> continue + ... try: + ... pipe.watch('OUR-SEQUENCE-KEY') + ... ... + ... pipe.execute() + ... break + ... except WatchError: + ... continue + ... finally: + ... pipe.reset() + ## API Reference |