(no subject)

Tuesday, 15 January 2013 10:09
gns_ua: (russe)
[personal profile] gns_ua
Вот оно чо.

[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(), тока вот опять же их собственный враппер не таков.
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

gns_ua: (Default)
gns_ua

April 2017

M T W T F S S
     12
3456789
10111213141516
17181920212223
24252627282930

Expand Cut Tags

No cut tags