(no subject)
Tuesday, 15 January 2013 10:09![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Вот оно чо.
В monitor видно, что херню делает:
Зато вот такое, без вотча:
Делает:
Всё правильно. Тогда какого?
Можно сперва запайпить, а потом уж ставить вотч и экзекать. Это работает:
И я бы даже смирился, да вот беда - их собственный враппер делает сначала watch, а потом отдаёт пайп для работы:
В то время как в Pipeline прямо написано:
Т.е. если поставил вотч, все следующие команды выполняются напрямую! И можно ещё воспользоваться explicit transaction и сказать p.multi(), тока вот опять же их собственный враппер не таков.
[altlinux@eeelive ~]$ python -c 'import redis, time; r=redis.Redis(); p=r.pipeline(); p.watch("abc"); p.set("123", 1); time.sleep(5); p.execute()'
В monitor видно, что херню делает:
1358237927.046987 [0 127.0.0.1:51442] "WATCH" "abc"
1358237927.048088 [0 127.0.0.1:51442] "SET" "123" "1"
1358237932.053436 [0 127.0.0.1:51442] "MULTI"
1358237932.053582 [0 127.0.0.1:51442] "EXEC"
1358237932.054853 [0 127.0.0.1:51442] "UNWATCH"
Зато вот такое, без вотча:
$ python -c 'import redis, time; r=redis.Redis(); p=r.pipeline(); p.set("123", 1);time.sleep(2); p.execute()'
Делает:
1358237753.861087 [0 127.0.0.1:51420] "MULTI"
1358237753.861234 [0 127.0.0.1:51420] "SET" "123" "1"
1358237753.861319 [0 127.0.0.1:51420] "EXEC"
Всё правильно. Тогда какого?
Можно сперва запайпить, а потом уж ставить вотч и экзекать. Это работает:
$ python -c 'import redis, time; r=redis.Redis(); print r.get("abc"); p=r.pipeline(); p.set("abc", 1); p.watch("abc"); time.sleep(5); p.execute(); print r.get("abc");'
None
1
===============================
1358238142.575640 [0 127.0.0.1:51474] "GET" "abc"
1358238142.577093 [0 127.0.0.1:51474] "WATCH" "abc"
1358238147.579733 [0 127.0.0.1:51474] "MULTI"
1358238147.579892 [0 127.0.0.1:51474] "SET" "abc" "1"
1358238147.579977 [0 127.0.0.1:51474] "EXEC"
1358238147.581572 [0 127.0.0.1:51474] "UNWATCH"
1358238147.582558 [0 127.0.0.1:51474] "GET" "abc"
И я бы даже смирился, да вот беда - их собственный враппер делает сначала watch, а потом отдаёт пайп для работы:
def transaction(self, func, *watches, **kwargs):
"""
Convenience method for executing the callable `func` as a transaction
while watching all keys specified in `watches`. The 'func' callable
should expect a single arguement which is a Pipeline object.
"""
shard_hint = kwargs.pop('shard_hint', None)
with self.pipeline(True, shard_hint) as pipe:
while 1:
try:
if watches:
print "Watching %s" % watches
pipe.watch(*watches)
func(pipe)
return pipe.execute()
except WatchError:
import traceback
traceback.print_exc()
continue
В то время как в Pipeline прямо написано:
def execute_command(self, *args, **kwargs):
if (self.watching or args[0] == 'WATCH') and \
not self.explicit_transaction:
return self.immediate_execute_command(*args, **kwargs)
return self.pipeline_execute_command(*args, **kwargs)
Т.е. если поставил вотч, все следующие команды выполняются напрямую! И можно ещё воспользоваться explicit transaction и сказать p.multi(), тока вот опять же их собственный враппер не таков.