-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Description
I understand it's intended and documented, still it's seems so inconvenient, illogical and prohibits efficient use of pipelining (not MULTI).
Why pipe suddenly breaks when I call .watch()? It is still kind of pipe, but it doesn't work as one. Maybe, old 2.2 approach is not the best, but it didn't cause this confusion. I used .pipeline(transaction=false) to make pipeline and with a flag on to make atomic pipeline. Cluttering everything in on method is questionable but concept is clear. Now, we still use .pipeline() to get atomic pipeline until we don't use .watch() when we suddenly loose pipelining and using .multi() directly to get atomic, which makes things with MULTI very inconsistent.
My use case, implemented for redis-py 2.2:
# set up pipeline not for multi, but to avoid unneeded network roundtrips
pipe = redis_conn.pipeline(transaction=False)
pipe.watch(version_key, *conjs_keys)
# get something from redis
pipe.get(...)
pipe.sunion(...)
...
# ignore watch() result, gather all other
_, result1, result2, ... = pipe.execute()
if <some condition involving result*>:
redis_conn.unwatch()
else:
try:
txn = redis_conn.pipeline()
# Change something in redis
txn.delete(...)
txn.execute()
except WatchError:
<Optimistic locking failed: just redo everything.>Actual working example is here
https://github.com/Suor/django-cacheops/blob/master/cacheops/invalidation.py#L111