)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7353,"name":"Kevin Carter","email":"kevin@cloudnull.com","username":"cloudnull"},"change_message_id":"a8756b88484cc93efe813e0cbcc2715b70c2b3ac","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Julien Danjou \u003cjulien@danjou.info\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-11-18 12:31:46 +0100"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"etcd: driver with lock support"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: Ibac90b9b2a751eb4f502e2f8b723e5608dcaad18"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"ba8a016a_5eb0408a","line":7,"updated":"2015-11-18 18:48:51.000000000","message":"Can we set the topic to \"WIP : etcd: driver with lock support\" so folks know that its current work in progress?","commit_id":"f54f57167aa54c8bc5d05f30ec61d57d02656d7c"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"d28c2b06b62efe8ac9975c6ee37520bb80208829","unresolved":false,"context_lines":[{"line_number":4,"context_line":"Commit:     Julien Danjou \u003cjulien@danjou.info\u003e"},{"line_number":5,"context_line":"CommitDate: 2015-11-18 12:31:46 +0100"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"etcd: driver with lock support"},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"Change-Id: Ibac90b9b2a751eb4f502e2f8b723e5608dcaad18"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"ba8a016a_0b01006a","line":7,"in_reply_to":"ba8a016a_5eb0408a","updated":"2015-11-19 09:25:55.000000000","message":"This is not WIP. This works. Sorry! :p\n\nIt just lacks the membership side, but I\u0027ll add that later. That does not prevent the patch to being merged.","commit_id":"f54f57167aa54c8bc5d05f30ec61d57d02656d7c"}],"doc/source/compatibility.rst":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"c129451d354db864045e9753e77db1c1a784d9c7","unresolved":false,"context_lines":[{"line_number":24,"context_line":"Driver support"},{"line_number":25,"context_line":"--------------"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":28,"context_line":":py:class:`~tooz.drivers.file.FileDriver`    :py:class:`~tooz.drivers.ipc.IPCDriver`    :py:class:`~tooz.drivers.memcached.MemcachedDriver`    :py:class:`~tooz.drivers.mysql.MySQLDriver`    :py:class:`~tooz.drivers.pgsql.PostgresDriver`    :py:class:`~tooz.drivers.redis.RedisDriver`    :py:class:`~tooz.drivers.zake.ZakeDriver`    :py:class:`~tooz.drivers.zookeeper.KazooDriver`    :py:class:`~tooz.drivers.etcd.EtcdDriver`"},{"line_number":29,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":30,"context_line":"Yes                                          No                                         Yes                                                    No                                             No                                                Yes                                            Yes                                          Yes                                                No"}],"source_content_type":"text/x-rst","patch_set":13,"id":"1a7b0d38_e848ea89","line":27,"updated":"2015-12-22 19:16:30.000000000","message":"There should be a corresponding change in https://github.com/openstack/tooz/blob/master/tools/compat-matrix.py right? Did u tweak this manually?? (if so I feel sorry for u, ha).","commit_id":"1e283c716684282e207706cd8879751d77a0824b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"e4f3e0c828fbc38aef0e54191c791a3e3604ff50","unresolved":false,"context_lines":[{"line_number":24,"context_line":"Driver support"},{"line_number":25,"context_line":"--------------"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":28,"context_line":":py:class:`~tooz.drivers.file.FileDriver`    :py:class:`~tooz.drivers.ipc.IPCDriver`    :py:class:`~tooz.drivers.memcached.MemcachedDriver`    :py:class:`~tooz.drivers.mysql.MySQLDriver`    :py:class:`~tooz.drivers.pgsql.PostgresDriver`    :py:class:`~tooz.drivers.redis.RedisDriver`    :py:class:`~tooz.drivers.zake.ZakeDriver`    :py:class:`~tooz.drivers.zookeeper.KazooDriver`    :py:class:`~tooz.drivers.etcd.EtcdDriver`"},{"line_number":29,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":30,"context_line":"Yes                                          No                                         Yes                                                    No                                             No                                                Yes                                            Yes                                          Yes                                                No"}],"source_content_type":"text/x-rst","patch_set":13,"id":"1a7b0d38_a66d2e34","line":27,"in_reply_to":"1a7b0d38_e848ea89","updated":"2015-12-22 22:15:07.000000000","message":"Lol, cry less, I def didn\u0027t manually make these tables back when this was added, that would be a FML situation, lol.","commit_id":"1e283c716684282e207706cd8879751d77a0824b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"3dc3230844e6292e4cd49dabaf5e6193a9c7f0a2","unresolved":false,"context_lines":[{"line_number":24,"context_line":"Driver support"},{"line_number":25,"context_line":"--------------"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":28,"context_line":":py:class:`~tooz.drivers.file.FileDriver`    :py:class:`~tooz.drivers.ipc.IPCDriver`    :py:class:`~tooz.drivers.memcached.MemcachedDriver`    :py:class:`~tooz.drivers.mysql.MySQLDriver`    :py:class:`~tooz.drivers.pgsql.PostgresDriver`    :py:class:`~tooz.drivers.redis.RedisDriver`    :py:class:`~tooz.drivers.zake.ZakeDriver`    :py:class:`~tooz.drivers.zookeeper.KazooDriver`    :py:class:`~tooz.drivers.etcd.EtcdDriver`"},{"line_number":29,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":30,"context_line":"Yes                                          No                                         Yes                                                    No                                             No                                                Yes                                            Yes                                          Yes                                                No"}],"source_content_type":"text/x-rst","patch_set":13,"id":"1a7b0d38_6662e6da","line":27,"in_reply_to":"1a7b0d38_e848ea89","updated":"2015-12-22 21:54:46.000000000","message":"Now I\u0027m crying.","commit_id":"1e283c716684282e207706cd8879751d77a0824b"}],"requirements.txt":[{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"00832631853a100b557c44489cec7756a7549b4b","unresolved":false,"context_lines":[{"line_number":14,"context_line":"futurist\u003e\u003d0.1.2 # Apache-2.0"},{"line_number":15,"context_line":"oslo.utils\u003e\u003d2.8.0 # Apache-2.0"},{"line_number":16,"context_line":"oslo.serialization\u003e\u003d1.10.0 # Apache-2.0"},{"line_number":17,"context_line":"requests\u003e\u003d2.5.2,!\u003d2.8.0"}],"source_content_type":"text/plain","patch_set":9,"id":"7a740942_2c7c36b4","line":17,"updated":"2015-12-11 18:36:43.000000000","message":"https://git.openstack.org/cgit/openstack/requirements/tree/global-requirements.txt#n195 \n\nThe requirement should be\n\n    requests\u003e\u003d2.8.1","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"3f98c091ea1c23f894a7216bfdf8fd84204cc8a3","unresolved":false,"context_lines":[{"line_number":14,"context_line":"futurist\u003e\u003d0.1.2 # Apache-2.0"},{"line_number":15,"context_line":"oslo.utils\u003e\u003d2.8.0 # Apache-2.0"},{"line_number":16,"context_line":"oslo.serialization\u003e\u003d1.10.0 # Apache-2.0"},{"line_number":17,"context_line":"requests\u003e\u003d2.5.2,!\u003d2.8.0"}],"source_content_type":"text/plain","patch_set":9,"id":"3a7e1126_0facf3eb","line":17,"in_reply_to":"7a740942_2c7c36b4","updated":"2015-12-18 10:00:01.000000000","message":"Done","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"}],"setup-etcd-env.sh":[{"author":{"_account_id":7353,"name":"Kevin Carter","email":"kevin@cloudnull.com","username":"cloudnull"},"change_message_id":"a8756b88484cc93efe813e0cbcc2715b70c2b3ac","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"ba8a016a_03a90324","updated":"2015-11-18 18:48:51.000000000","message":"can this be extended to pull down a local stable build of etcd to test against which would help the test case in the general assumption that ectd is already installed globally?","commit_id":"f54f57167aa54c8bc5d05f30ec61d57d02656d7c"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"d28c2b06b62efe8ac9975c6ee37520bb80208829","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"ba8a016a_2b2de4fd","in_reply_to":"ba8a016a_03a90324","updated":"2015-11-19 09:25:55.000000000","message":"No, this is definitely not the goal of this!","commit_id":"f54f57167aa54c8bc5d05f30ec61d57d02656d7c"},{"author":{"_account_id":10263,"name":"Vilobh Meshram","email":"vilobhmm@yahoo-inc.com","username":"vilobhmm"},"change_message_id":"736aa0183164a5f0f27f9da7f777de7cbb7ade00","unresolved":false,"context_lines":[{"line_number":8,"context_line":"}"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"trap clean_exit EXIT"},{"line_number":11,"context_line":"if [ -n \"$(which etcd)\" ]; then"},{"line_number":12,"context_line":"    etcd \u0026"},{"line_number":13,"context_line":"fi"},{"line_number":14,"context_line":""}],"source_content_type":"text/x-sh","patch_set":5,"id":"7a740942_e2e6c0e7","line":11,"updated":"2015-12-03 19:54:17.000000000","message":"How is etcd going to get installed ?","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"2786697e9033fa7d44b85efb1b57964ce6f6b5a3","unresolved":false,"context_lines":[{"line_number":8,"context_line":"}"},{"line_number":9,"context_line":""},{"line_number":10,"context_line":"trap clean_exit EXIT"},{"line_number":11,"context_line":"if [ -n \"$(which etcd)\" ]; then"},{"line_number":12,"context_line":"    etcd \u0026"},{"line_number":13,"context_line":"fi"},{"line_number":14,"context_line":""}],"source_content_type":"text/x-sh","patch_set":5,"id":"7a740942_346e2630","line":11,"in_reply_to":"7a740942_e2e6c0e7","updated":"2015-12-04 11:33:17.000000000","message":"apt-get install it?\n\nI\u0027ve build a patch to install it on infra.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"}],"tooz/default.etcd/member/wal/0000000000000000-0000000000000000.wal":[{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"617339de4f2c4b764bd6c6a4220303ad6ff95a74","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"1a7b0d38_089536e3","updated":"2015-12-22 19:15:03.000000000","message":"What the, lol.","commit_id":"1e283c716684282e207706cd8879751d77a0824b"}],"tooz/drivers/etcd.py":[{"author":{"_account_id":7353,"name":"Kevin Carter","email":"kevin@cloudnull.com","username":"cloudnull"},"change_message_id":"3fad4d902826c0f033ebb08ad8695d232fc33a22","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"ba8a016a_484e4a3c","updated":"2015-11-18 18:31:11.000000000","message":"Is there any reason not to run with the python etcd bindings found here: https://pypi.python.org/pypi/python-etcd or here: https://pypi.python.org/pypi/etcd ? Seems like we may be able to benefit from some of the already existent clients.","commit_id":"f54f57167aa54c8bc5d05f30ec61d57d02656d7c"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"6cff6e5cdce04dda62f757c15e4ec85b15415497","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        poked \u003d self.client.put(self._lock_url,"},{"line_number":110,"context_line":"                                data\u003d{\"ttl\": self.ttl,"},{"line_number":111,"context_line":"                                      \"prevExist\": \"true\"})"},{"line_number":112,"context_line":"        if poked.get(\"errorCode\"):"},{"line_number":113,"context_line":"            LOG.warn(\"Unable to heartbeat by updating key \u0027%s\u0027 with extended\""},{"line_number":114,"context_line":"                     \" expiry of %s seconds\", self.name, self.ttl)"},{"line_number":115,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ba8a016a_77b19b46","line":112,"updated":"2015-11-19 00:30:45.000000000","message":"Add in the error code (or other response data?) into the log message?","commit_id":"f54f57167aa54c8bc5d05f30ec61d57d02656d7c"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"d28c2b06b62efe8ac9975c6ee37520bb80208829","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        poked \u003d self.client.put(self._lock_url,"},{"line_number":110,"context_line":"                                data\u003d{\"ttl\": self.ttl,"},{"line_number":111,"context_line":"                                      \"prevExist\": \"true\"})"},{"line_number":112,"context_line":"        if poked.get(\"errorCode\"):"},{"line_number":113,"context_line":"            LOG.warn(\"Unable to heartbeat by updating key \u0027%s\u0027 with extended\""},{"line_number":114,"context_line":"                     \" expiry of %s seconds\", self.name, self.ttl)"},{"line_number":115,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ba8a016a_2b14049e","line":112,"in_reply_to":"ba8a016a_77b19b46","updated":"2015-11-19 09:25:55.000000000","message":"ack","commit_id":"f54f57167aa54c8bc5d05f30ec61d57d02656d7c"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"30092d82614aa83177e9b1a37369c0dea9a22b01","unresolved":false,"context_lines":[{"line_number":85,"context_line":"            reply \u003d self.client.put(self._lock_url,"},{"line_number":86,"context_line":"                                    data\u003d{\"ttl\": self.ttl,"},{"line_number":87,"context_line":"                                          \"prevExist\": \"false\"})"},{"line_number":88,"context_line":"            print(reply)"},{"line_number":89,"context_line":"            if reply.get(\"errorCode\") is None:"},{"line_number":90,"context_line":"                self.coord._acquired_locks.append(self)"},{"line_number":91,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":2,"id":"ba8a016a_6498e01c","line":88,"updated":"2015-11-19 16:15:28.000000000","message":"Remove this? ;)","commit_id":"0d463e88c7f23c47b5b4de3bf4270abac876f4e4"},{"author":{"_account_id":6488,"name":"Clint Byrum","email":"clint@fewbar.com","username":"clint-fewbar"},"change_message_id":"bab92ac0a84152983a4765fc93e45e8d58528ae0","unresolved":false,"context_lines":[{"line_number":74,"context_line":"        self.coord \u003d coord"},{"line_number":75,"context_line":"        self.lock \u003d None"},{"line_number":76,"context_line":"        self.ttl \u003d ttl"},{"line_number":77,"context_line":"        # NOTE(jd) sha1 of the name to be sure it works with any string?"},{"line_number":78,"context_line":"        self._lock_url \u003d \"/keys/\" + self._TOOZ_LOCK_PREFIX + \"/\" + name"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def acquire(self, blocking\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba8a016a_b4058c46","line":77,"updated":"2015-11-19 19:37:19.000000000","message":"IMO it should not work with any string. That is WAY too broad. Having it be human readable is important for ops.","commit_id":"0acee434c7e4078d00308d0cbcca43cae175e092"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"90425469e97b08793659e3141471b5840fb2cf17","unresolved":false,"context_lines":[{"line_number":74,"context_line":"        self.coord \u003d coord"},{"line_number":75,"context_line":"        self.lock \u003d None"},{"line_number":76,"context_line":"        self.ttl \u003d ttl"},{"line_number":77,"context_line":"        # NOTE(jd) sha1 of the name to be sure it works with any string?"},{"line_number":78,"context_line":"        self._lock_url \u003d \"/keys/\" + self._TOOZ_LOCK_PREFIX + \"/\" + name"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def acquire(self, blocking\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba8a016a_a1a3f3fe","line":77,"in_reply_to":"ba8a016a_947abdbb","updated":"2015-11-20 08:46:58.000000000","message":"Yeah, typically / is not going to work for example or cause funny stuff: if you create a lock named foobar and then a lock named foobar/baz it will fail.","commit_id":"0acee434c7e4078d00308d0cbcca43cae175e092"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"2f20cf473305f15c066948adfb90592e176c5ad3","unresolved":false,"context_lines":[{"line_number":74,"context_line":"        self.coord \u003d coord"},{"line_number":75,"context_line":"        self.lock \u003d None"},{"line_number":76,"context_line":"        self.ttl \u003d ttl"},{"line_number":77,"context_line":"        # NOTE(jd) sha1 of the name to be sure it works with any string?"},{"line_number":78,"context_line":"        self._lock_url \u003d \"/keys/\" + self._TOOZ_LOCK_PREFIX + \"/\" + name"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def acquire(self, blocking\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba8a016a_947abdbb","line":77,"in_reply_to":"ba8a016a_b4058c46","updated":"2015-11-19 23:35:05.000000000","message":"Why does this need to potentially use sha1? Does \"..\" do special things in the keyspace? Are there length restrictions, or something else (btw, urls above 4096 characters typically start to cause funkyness in lots of places, especially in any caching server/s)?\n\nI mean in general u probably need to urlencode the \u0027name\u0027 here but this is just typically stuff i think.","commit_id":"0acee434c7e4078d00308d0cbcca43cae175e092"},{"author":{"_account_id":6488,"name":"Clint Byrum","email":"clint@fewbar.com","username":"clint-fewbar"},"change_message_id":"bab92ac0a84152983a4765fc93e45e8d58528ae0","unresolved":false,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def acquire(self, blocking\u003dTrue):"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"        @_retry.retry(stop_max_delay\u003dblocking)"},{"line_number":83,"context_line":"        @_translate_failures"},{"line_number":84,"context_line":"        def _acquire():"},{"line_number":85,"context_line":"            reply \u003d self.client.put(self._lock_url,"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba8a016a_378bde20","line":82,"updated":"2015-11-19 19:37:19.000000000","message":"Isn\u0027t stop_max_delay supposed to be an int?","commit_id":"0acee434c7e4078d00308d0cbcca43cae175e092"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"2f20cf473305f15c066948adfb90592e176c5ad3","unresolved":false,"context_lines":[{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def acquire(self, blocking\u003dTrue):"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"        @_retry.retry(stop_max_delay\u003dblocking)"},{"line_number":83,"context_line":"        @_translate_failures"},{"line_number":84,"context_line":"        def _acquire():"},{"line_number":85,"context_line":"            reply \u003d self.client.put(self._lock_url,"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba8a016a_0f0b1a25","line":82,"in_reply_to":"ba8a016a_378bde20","updated":"2015-11-19 23:35:05.000000000","message":"Ah, u just discovered the dual natural of this var, not our finest moment/decision imho but blocking can be a boolean (block or not) or if a float it is the amount of time to block for...","commit_id":"0acee434c7e4078d00308d0cbcca43cae175e092"},{"author":{"_account_id":6488,"name":"Clint Byrum","email":"clint@fewbar.com","username":"clint-fewbar"},"change_message_id":"bab92ac0a84152983a4765fc93e45e8d58528ae0","unresolved":false,"context_lines":[{"line_number":90,"context_line":"                return True"},{"line_number":91,"context_line":"            if blocking is False:"},{"line_number":92,"context_line":"                return False"},{"line_number":93,"context_line":"            raise _retry.Retry"},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"        return _acquire()"},{"line_number":96,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"ba8a016a_d475b0ca","line":93,"updated":"2015-11-19 19:37:19.000000000","message":"There\u0027s no need to poll, I believe you can just use a get with wait\u003dtrue and, waitIndex using the \u0027index\u0027 that the put returns, to wait until the node is deleted.\n\nhttps://coreos.com/etcd/docs/latest/api.html#waiting-for-a-change","commit_id":"0acee434c7e4078d00308d0cbcca43cae175e092"},{"author":{"_account_id":6488,"name":"Clint Byrum","email":"clint@fewbar.com","username":"clint-fewbar"},"change_message_id":"bab92ac0a84152983a4765fc93e45e8d58528ae0","unresolved":false,"context_lines":[{"line_number":96,"context_line":""},{"line_number":97,"context_line":"    @_translate_failures"},{"line_number":98,"context_line":"    def release(self):"},{"line_number":99,"context_line":"        reply \u003d self.client.delete(self._lock_url)"},{"line_number":100,"context_line":"        if reply.get(\"errorCode\") is None:"},{"line_number":101,"context_line":"            self.coord._acquired_locks.remove(self)"},{"line_number":102,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba8a016a_d7c85257","line":99,"updated":"2015-11-19 19:37:19.000000000","message":"I think it\u0027s a good idea to use prevIndex here and ensure that the lock hasn\u0027t been modified. If it has, that means something decided the lock we thought we had, we shouldn\u0027t, so that should be logged at WARN similar to the failed heartbeat.","commit_id":"0acee434c7e4078d00308d0cbcca43cae175e092"},{"author":{"_account_id":7353,"name":"Kevin Carter","email":"kevin@cloudnull.com","username":"cloudnull"},"change_message_id":"e442f6c7fc99f1ee9447774d6143491ee8779ee7","unresolved":false,"context_lines":[{"line_number":145,"context_line":""},{"line_number":146,"context_line":"    @staticmethod"},{"line_number":147,"context_line":"    def watch_join_group(group_id, callback):"},{"line_number":148,"context_line":"        raise tooz.NotImplemented"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"    @staticmethod"},{"line_number":151,"context_line":"    def unwatch_join_group(group_id, callback):"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba8a016a_05622b0a","line":148,"updated":"2015-11-19 18:20:45.000000000","message":"With all of the \"NotImplemented\" methods being in the base class do we need to redefine them using the same things? Seems like a waist especially as their being left exactly as-is in this initial proposal.","commit_id":"0acee434c7e4078d00308d0cbcca43cae175e092"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"90425469e97b08793659e3141471b5840fb2cf17","unresolved":false,"context_lines":[{"line_number":145,"context_line":""},{"line_number":146,"context_line":"    @staticmethod"},{"line_number":147,"context_line":"    def watch_join_group(group_id, callback):"},{"line_number":148,"context_line":"        raise tooz.NotImplemented"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"    @staticmethod"},{"line_number":151,"context_line":"    def unwatch_join_group(group_id, callback):"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba8a016a_41e1e728","line":148,"in_reply_to":"ba8a016a_05622b0a","updated":"2015-11-20 08:46:58.000000000","message":"Yes because they are abstract.","commit_id":"0acee434c7e4078d00308d0cbcca43cae175e092"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"7878b2070e71f2f179141f73f550df39a541336f","unresolved":false,"context_lines":[{"line_number":37,"context_line":"            return func(*args, **kwargs)"},{"line_number":38,"context_line":"        except (requests.exceptions.RequestException,"},{"line_number":39,"context_line":"                httplib.HTTPException) as e:"},{"line_number":40,"context_line":"            coordination.raise_with_cause(coordination.ToozConnectionError,"},{"line_number":41,"context_line":"                                          utils.exception_message(e),"},{"line_number":42,"context_line":"                                          cause\u003de)"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_83bd7704","line":40,"updated":"2015-11-30 20:57:09.000000000","message":"I wonder if we should do a better job here at raising different errors, it would seem like only some of these are connection errors and likely some are non-connection errors (do the http codes that are given back allow u to distingush?)","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"e83d97089c1dbce9af34cba9b809b7f971592a53","unresolved":false,"context_lines":[{"line_number":37,"context_line":"            return func(*args, **kwargs)"},{"line_number":38,"context_line":"        except (requests.exceptions.RequestException,"},{"line_number":39,"context_line":"                httplib.HTTPException) as e:"},{"line_number":40,"context_line":"            coordination.raise_with_cause(coordination.ToozConnectionError,"},{"line_number":41,"context_line":"                                          utils.exception_message(e),"},{"line_number":42,"context_line":"                                          cause\u003de)"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_eb55bf1d","line":40,"in_reply_to":"9a8ffd7b_474e96c2","updated":"2015-12-02 16:49:52.000000000","message":"I\u0027m pretty sure \u0027RequestException\u0027 has the http code on it that u could use to raise more specific exceptions? Anyways, maybe something for the future...","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"75dbf4821ce353d1f8bf59c6c1ffe59cd33b85fc","unresolved":false,"context_lines":[{"line_number":37,"context_line":"            return func(*args, **kwargs)"},{"line_number":38,"context_line":"        except (requests.exceptions.RequestException,"},{"line_number":39,"context_line":"                httplib.HTTPException) as e:"},{"line_number":40,"context_line":"            coordination.raise_with_cause(coordination.ToozConnectionError,"},{"line_number":41,"context_line":"                                          utils.exception_message(e),"},{"line_number":42,"context_line":"                                          cause\u003de)"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_474e96c2","line":40,"in_reply_to":"9a8ffd7b_83bd7704","updated":"2015-12-01 12:47:14.000000000","message":"I don\u0027t think requests raises anything if the connection sucess with a 4xx or 5xx error code?","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"2786697e9033fa7d44b85efb1b57964ce6f6b5a3","unresolved":false,"context_lines":[{"line_number":37,"context_line":"            return func(*args, **kwargs)"},{"line_number":38,"context_line":"        except (requests.exceptions.RequestException,"},{"line_number":39,"context_line":"                httplib.HTTPException) as e:"},{"line_number":40,"context_line":"            coordination.raise_with_cause(coordination.ToozConnectionError,"},{"line_number":41,"context_line":"                                          utils.exception_message(e),"},{"line_number":42,"context_line":"                                          cause\u003de)"},{"line_number":43,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_f44e5ec0","line":40,"in_reply_to":"9a8ffd7b_eb55bf1d","updated":"2015-12-04 11:33:17.000000000","message":"I don\u0027t see exactly how more specific it can be. If you have example we can improve after I guess.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":10263,"name":"Vilobh Meshram","email":"vilobhmm@yahoo-inc.com","username":"vilobhmm"},"change_message_id":"736aa0183164a5f0f27f9da7f777de7cbb7ade00","unresolved":false,"context_lines":[{"line_number":46,"context_line":""},{"line_number":47,"context_line":"class _Client(object):"},{"line_number":48,"context_line":"    def __init__(self, host, port, protocol):"},{"line_number":49,"context_line":"        self.host \u003d host"},{"line_number":50,"context_line":"        self.port \u003d port"},{"line_number":51,"context_line":"        self.protocol \u003d protocol"},{"line_number":52,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_c2ce245a","line":49,"updated":"2015-12-03 19:54:17.000000000","message":"Appreciate if these can be made private","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":10263,"name":"Vilobh Meshram","email":"vilobhmm@yahoo-inc.com","username":"vilobhmm"},"change_message_id":"736aa0183164a5f0f27f9da7f777de7cbb7ade00","unresolved":false,"context_lines":[{"line_number":47,"context_line":"class _Client(object):"},{"line_number":48,"context_line":"    def __init__(self, host, port, protocol):"},{"line_number":49,"context_line":"        self.host \u003d host"},{"line_number":50,"context_line":"        self.port \u003d port"},{"line_number":51,"context_line":"        self.protocol \u003d protocol"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @property"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_82d81c1f","line":50,"updated":"2015-12-03 19:54:17.000000000","message":"ditto","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":10263,"name":"Vilobh Meshram","email":"vilobhmm@yahoo-inc.com","username":"vilobhmm"},"change_message_id":"736aa0183164a5f0f27f9da7f777de7cbb7ade00","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    def __init__(self, host, port, protocol):"},{"line_number":49,"context_line":"        self.host \u003d host"},{"line_number":50,"context_line":"        self.port \u003d port"},{"line_number":51,"context_line":"        self.protocol \u003d protocol"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @property"},{"line_number":54,"context_line":"    def base_url(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_2204c87c","line":51,"updated":"2015-12-03 19:54:17.000000000","message":"ditto","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"d974cb8584218e7c40c971d444ce77f85b81bdd1","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        self.host \u003d host"},{"line_number":50,"context_line":"        self.port \u003d port"},{"line_number":51,"context_line":"        self.protocol \u003d protocol"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @property"},{"line_number":54,"context_line":"    def base_url(self):"},{"line_number":55,"context_line":"        return self.protocol + \u0027://\u0027 + self.host + \u0027:\u0027 + str(self.port)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_c5aceeef","line":52,"updated":"2015-12-03 19:57:31.000000000","message":"IMHO: the whole class is private, so I\u0027m not sure it matters if the attributes are as well.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"2786697e9033fa7d44b85efb1b57964ce6f6b5a3","unresolved":false,"context_lines":[{"line_number":49,"context_line":"        self.host \u003d host"},{"line_number":50,"context_line":"        self.port \u003d port"},{"line_number":51,"context_line":"        self.protocol \u003d protocol"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @property"},{"line_number":54,"context_line":"    def base_url(self):"},{"line_number":55,"context_line":"        return self.protocol + \u0027://\u0027 + self.host + \u0027:\u0027 + str(self.port)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_54d972f2","line":52,"in_reply_to":"7a740942_c5aceeef","updated":"2015-12-04 11:33:17.000000000","message":"Yeah, not sure I see the point otherwise.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"7878b2070e71f2f179141f73f550df39a541336f","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        reply \u003d self.client.delete(self._lock_url)"},{"line_number":127,"context_line":"        if reply.get(\"errorCode\") is None:"},{"line_number":128,"context_line":"            self.coord._acquired_locks.remove(self)"},{"line_number":129,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_030e67e5","line":126,"updated":"2015-11-30 20:57:09.000000000","message":"Should this check if the lock was acquired int the first place, probably something we need to do better on, since I think some lock impls check and some don\u0027t...","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"2786697e9033fa7d44b85efb1b57964ce6f6b5a3","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        reply \u003d self.client.delete(self._lock_url)"},{"line_number":127,"context_line":"        if reply.get(\"errorCode\") is None:"},{"line_number":128,"context_line":"            self.coord._acquired_locks.remove(self)"},{"line_number":129,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_f493bef8","line":126,"in_reply_to":"7a740942_050e7634","updated":"2015-12-04 11:33:17.000000000","message":"If I MUST CHECK as you say, I\u0027ll need to write a test that assert that the current code I wrote is wrong. And I\u0027m pretty sure this is going to raise a bunch of issues in the other driver.\n\nSo, because I\u0027m a nice guy and I like working on tooz I\u0027m going to do that, but actually, I don\u0027t need to do that currently to have this driver.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":6488,"name":"Clint Byrum","email":"clint@fewbar.com","username":"clint-fewbar"},"change_message_id":"5662e6157f22a3b7587e9122da63be2aea87f5d1","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        reply \u003d self.client.delete(self._lock_url)"},{"line_number":127,"context_line":"        if reply.get(\"errorCode\") is None:"},{"line_number":128,"context_line":"            self.coord._acquired_locks.remove(self)"},{"line_number":129,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_23001501","line":126,"in_reply_to":"7a740942_275fd342","updated":"2015-12-04 18:34:11.000000000","message":"Thanks Julien. I do think you\u0027re a very nice guy for submitting that test, and I also think we should fix File and Memcache. Both of them can be made to work correctly! This stuff is hard and takes time to mature, and I think it\u0027s ok if we find holes in other stuff because of new drivers. I\u0027d say at least half of the value in Tooz is in the test suite.. so it\u0027s good to flesh it out with known scenarios.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"49c9cdb1fc26f93d517f972427f2e9ccb83e33a9","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        reply \u003d self.client.delete(self._lock_url)"},{"line_number":127,"context_line":"        if reply.get(\"errorCode\") is None:"},{"line_number":128,"context_line":"            self.coord._acquired_locks.remove(self)"},{"line_number":129,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_275fd342","line":126,"in_reply_to":"7a740942_f493bef8","updated":"2015-12-04 12:59:13.000000000","message":"So the test is actually what I already sent here https://review.openstack.org/#/c/249200/\n\nAnd it fails for the File driver and Memcache driver.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":6488,"name":"Clint Byrum","email":"clint@fewbar.com","username":"clint-fewbar"},"change_message_id":"999d0f684d186a597e0f879594bc86feb0d2498b","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        reply \u003d self.client.delete(self._lock_url)"},{"line_number":127,"context_line":"        if reply.get(\"errorCode\") is None:"},{"line_number":128,"context_line":"            self.coord._acquired_locks.remove(self)"},{"line_number":129,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_65af2e95","line":126,"in_reply_to":"9a8ffd7b_030e67e5","updated":"2015-12-03 19:50:56.000000000","message":"YOU MUST check! If you don\u0027t hold the lock, and you delete it, you have just broken the lock for whoever holds it.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"75dbf4821ce353d1f8bf59c6c1ffe59cd33b85fc","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        reply \u003d self.client.delete(self._lock_url)"},{"line_number":127,"context_line":"        if reply.get(\"errorCode\") is None:"},{"line_number":128,"context_line":"            self.coord._acquired_locks.remove(self)"},{"line_number":129,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_87db1eed","line":126,"in_reply_to":"9a8ffd7b_030e67e5","updated":"2015-12-01 12:47:14.000000000","message":"Yes, that\u0027s one of the point of my patch with tests only. This behaviour is undetermined.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"e2725b1bb247e0ae90c995f194e58e986e0b91cc","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        reply \u003d self.client.delete(self._lock_url)"},{"line_number":127,"context_line":"        if reply.get(\"errorCode\") is None:"},{"line_number":128,"context_line":"            self.coord._acquired_locks.remove(self)"},{"line_number":129,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_050e7634","line":126,"in_reply_to":"9a8ffd7b_65af2e95","updated":"2015-12-03 19:54:57.000000000","message":"Good point, hopefully there can be some kind of \u0027expected_owner\u0027 that delete() takes (and u pass it yourself and if its not yourself nothing gets deleted)....","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":10263,"name":"Vilobh Meshram","email":"vilobhmm@yahoo-inc.com","username":"vilobhmm"},"change_message_id":"736aa0183164a5f0f27f9da7f777de7cbb7ade00","unresolved":false,"context_lines":[{"line_number":149,"context_line":""},{"line_number":150,"context_line":"    def __init__(self, member_id, parsed_url, options):"},{"line_number":151,"context_line":"        super(EtcdDriver, self).__init__()"},{"line_number":152,"context_line":"        self.client \u003d _Client(host\u003dparsed_url.hostname,"},{"line_number":153,"context_line":"                              port\u003dparsed_url.port,"},{"line_number":154,"context_line":"                              protocol\u003doptions.get(\u0027protocol\u0027, \u0027http\u0027))"},{"line_number":155,"context_line":"        default_timeout \u003d options.get(\u0027timeout\u0027, self.DEFAULT_TIMEOUT)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_a2f8b87d","line":152,"updated":"2015-12-03 19:54:17.000000000","message":"ditto","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"2786697e9033fa7d44b85efb1b57964ce6f6b5a3","unresolved":false,"context_lines":[{"line_number":149,"context_line":""},{"line_number":150,"context_line":"    def __init__(self, member_id, parsed_url, options):"},{"line_number":151,"context_line":"        super(EtcdDriver, self).__init__()"},{"line_number":152,"context_line":"        self.client \u003d _Client(host\u003dparsed_url.hostname,"},{"line_number":153,"context_line":"                              port\u003dparsed_url.port,"},{"line_number":154,"context_line":"                              protocol\u003doptions.get(\u0027protocol\u0027, \u0027http\u0027))"},{"line_number":155,"context_line":"        default_timeout \u003d options.get(\u0027timeout\u0027, self.DEFAULT_TIMEOUT)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_34b14690","line":152,"in_reply_to":"7a740942_a2f8b87d","updated":"2015-12-04 11:33:17.000000000","message":"Ok for this one.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":10263,"name":"Vilobh Meshram","email":"vilobhmm@yahoo-inc.com","username":"vilobhmm"},"change_message_id":"736aa0183164a5f0f27f9da7f777de7cbb7ade00","unresolved":false,"context_lines":[{"line_number":153,"context_line":"                              port\u003dparsed_url.port,"},{"line_number":154,"context_line":"                              protocol\u003doptions.get(\u0027protocol\u0027, \u0027http\u0027))"},{"line_number":155,"context_line":"        default_timeout \u003d options.get(\u0027timeout\u0027, self.DEFAULT_TIMEOUT)"},{"line_number":156,"context_line":"        self.lock_timeout \u003d int(options.get("},{"line_number":157,"context_line":"            \u0027lock_timeout\u0027, default_timeout))"},{"line_number":158,"context_line":"        self._acquired_locks \u003d []"},{"line_number":159,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_62f2d09c","line":156,"updated":"2015-12-03 19:54:17.000000000","message":"ditto","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"7878b2070e71f2f179141f73f550df39a541336f","unresolved":false,"context_lines":[{"line_number":166,"context_line":"    def get_lock(self, name):"},{"line_number":167,"context_line":"        return EtcdLock(name, self, self.client, self.lock_timeout)"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    def heartbeat(self):"},{"line_number":170,"context_line":"        for lock in self._acquired_locks:"},{"line_number":171,"context_line":"            lock.heartbeat()"},{"line_number":172,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_0325075b","line":169,"updated":"2015-11-30 20:57:09.000000000","message":"Is there any session heartbeat that needs to be maintained with etcd, something to keep the etcd server from thinking this session is dead?","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":6488,"name":"Clint Byrum","email":"clint@fewbar.com","username":"clint-fewbar"},"change_message_id":"5662e6157f22a3b7587e9122da63be2aea87f5d1","unresolved":false,"context_lines":[{"line_number":166,"context_line":"    def get_lock(self, name):"},{"line_number":167,"context_line":"        return EtcdLock(name, self, self.client, self.lock_timeout)"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    def heartbeat(self):"},{"line_number":170,"context_line":"        for lock in self._acquired_locks:"},{"line_number":171,"context_line":"            lock.heartbeat()"},{"line_number":172,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_c6cd9f5e","line":169,"in_reply_to":"7a740942_14a8ca1e","updated":"2015-12-04 18:34:11.000000000","message":"Oh, so you could lose the lock just by the virtue of your operation taking too long?","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"75dbf4821ce353d1f8bf59c6c1ffe59cd33b85fc","unresolved":false,"context_lines":[{"line_number":166,"context_line":"    def get_lock(self, name):"},{"line_number":167,"context_line":"        return EtcdLock(name, self, self.client, self.lock_timeout)"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    def heartbeat(self):"},{"line_number":170,"context_line":"        for lock in self._acquired_locks:"},{"line_number":171,"context_line":"            lock.heartbeat()"},{"line_number":172,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_47e536a6","line":169,"in_reply_to":"9a8ffd7b_0325075b","updated":"2015-12-01 12:47:14.000000000","message":"It\u0027s stateless HTTP.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":6488,"name":"Clint Byrum","email":"clint@fewbar.com","username":"clint-fewbar"},"change_message_id":"999d0f684d186a597e0f879594bc86feb0d2498b","unresolved":false,"context_lines":[{"line_number":166,"context_line":"    def get_lock(self, name):"},{"line_number":167,"context_line":"        return EtcdLock(name, self, self.client, self.lock_timeout)"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    def heartbeat(self):"},{"line_number":170,"context_line":"        for lock in self._acquired_locks:"},{"line_number":171,"context_line":"            lock.heartbeat()"},{"line_number":172,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"9a8ffd7b_cf5027d7","line":169,"in_reply_to":"9a8ffd7b_0325075b","updated":"2015-12-03 19:50:56.000000000","message":"Right, this is required, otherwise what else helps etcd know the session is alive?","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"2786697e9033fa7d44b85efb1b57964ce6f6b5a3","unresolved":false,"context_lines":[{"line_number":166,"context_line":"    def get_lock(self, name):"},{"line_number":167,"context_line":"        return EtcdLock(name, self, self.client, self.lock_timeout)"},{"line_number":168,"context_line":""},{"line_number":169,"context_line":"    def heartbeat(self):"},{"line_number":170,"context_line":"        for lock in self._acquired_locks:"},{"line_number":171,"context_line":"            lock.heartbeat()"},{"line_number":172,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a740942_14a8ca1e","line":169,"in_reply_to":"9a8ffd7b_cf5027d7","updated":"2015-12-04 11:33:17.000000000","message":"There is no session in etcd. It\u0027s stateless. It\u0027s based on TTL.","commit_id":"9f609d0f41759aeb02f818838266628b84c3d8f4"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"03cd75b8ea1ea6aa55e647a2a4d6b9b91e614001","unresolved":false,"context_lines":[{"line_number":11,"context_line":"# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import httplib"},{"line_number":16,"context_line":"import logging"},{"line_number":17,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_9db316e9","line":14,"updated":"2015-12-07 20:51:07.000000000","message":"Requests pops out httplib errors?","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"65d2f18b7fe351eaddf75f31ac4adef657583780","unresolved":false,"context_lines":[{"line_number":11,"context_line":"# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import httplib"},{"line_number":16,"context_line":"import logging"},{"line_number":17,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_ab79ccc9","line":14,"in_reply_to":"7a740942_9db316e9","updated":"2015-12-08 10:29:57.000000000","message":"Yes, for real (tested)","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"f9c871985b36a6586838de5052099be80d09b1ee","unresolved":false,"context_lines":[{"line_number":11,"context_line":"# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import httplib"},{"line_number":16,"context_line":"import logging"},{"line_number":17,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_581b4781","line":14,"in_reply_to":"7a740942_ab79ccc9","updated":"2015-12-08 16:56:09.000000000","message":"Thats crazy.","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"334e0337a7360f5b6f528a2df04b30d8fdecaf5a","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        if self in self.coord._acquired_locks:"},{"line_number":127,"context_line":"            reply \u003d self.client.delete(self._lock_url)"},{"line_number":128,"context_line":"            if reply.get(\"errorCode\") is None:"},{"line_number":129,"context_line":"                self.coord._acquired_locks.remove(self)"},{"line_number":130,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_e2c15555","line":127,"updated":"2015-12-07 20:33:05.000000000","message":"This still scares me because it can pretty much release anyones lock :-P","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"63be307b04149c74742feaf59265931e035bfbe9","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        if self in self.coord._acquired_locks:"},{"line_number":127,"context_line":"            reply \u003d self.client.delete(self._lock_url)"},{"line_number":128,"context_line":"            if reply.get(\"errorCode\") is None:"},{"line_number":129,"context_line":"                self.coord._acquired_locks.remove(self)"},{"line_number":130,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_7e3dcb8d","line":127,"in_reply_to":"7a740942_38d3dbd6","updated":"2015-12-08 17:15:15.000000000","message":"Yeah I think this scenario is possible and will fail. Problem is that this is already a problem with memcached and probably a lot of other backends.\n\nSo we need a test for that and fix all the other backends. This is orthogonal to this patch.","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":6488,"name":"Clint Byrum","email":"clint@fewbar.com","username":"clint-fewbar"},"change_message_id":"9fa9c2660229c5b96ffc4b003a01f1178ca964e8","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        if self in self.coord._acquired_locks:"},{"line_number":127,"context_line":"            reply \u003d self.client.delete(self._lock_url)"},{"line_number":128,"context_line":"            if reply.get(\"errorCode\") is None:"},{"line_number":129,"context_line":"                self.coord._acquired_locks.remove(self)"},{"line_number":130,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_9e051715","line":127,"in_reply_to":"7a740942_7e3dcb8d","updated":"2015-12-08 17:38:35.000000000","message":"Funny you should mention that...\n\nhttps://review.openstack.org/#/c/253737/ is just that test. :)\n\nIf we agree with that approach on principle, then we should be able to agree that new drivers should implement break_lock if they can, and maybe even rebase on top of that patch.\n\nNote that the patch has to change memcached by getting the lock again and verifying the ID is still the same. This is racey (and an example of why our approach with the memcached driver is not OK IMO, we need to use CAS for release, soft timeouts, and advise users to run with -M), but we can at least expect _less_ mishaps with such a test in place. Unfortunately, races are basically impossible to test without being able to control clock-advances for every single component. But we can at least reason about them and minimize the areas in which we know a race is likely.\n\nIn the etcd case, we have compareAndDelete, which is what we should use here, and which should eliminate the race entirely:\n\nhttps://coreos.com/etcd/docs/latest/api.html\n\nI\u0027d suggest keeping the Index from the initial acquire, and use prevIndex in the delete. That should eliminate any chance of accidentally unlocking somebody else\u0027s acquisition.","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"58dd77f0f3cb20b5c0793964b955f691fd0a3bfc","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        if self in self.coord._acquired_locks:"},{"line_number":127,"context_line":"            reply \u003d self.client.delete(self._lock_url)"},{"line_number":128,"context_line":"            if reply.get(\"errorCode\") is None:"},{"line_number":129,"context_line":"                self.coord._acquired_locks.remove(self)"},{"line_number":130,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_d1db744d","line":127,"in_reply_to":"7a740942_7e3dcb8d","updated":"2015-12-09 06:27:09.000000000","message":"I get that we should do better, but we might as well IMHO do better upfront if we can. Redis redlock has provisions against this, so does zookeeper (the other drivers that are not really distributed will likely be affected); but one less driver we have to fix later IMHO is better.","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"ad7d6fe7403ce5d383768c8ef41378849f0db82d","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        if self in self.coord._acquired_locks:"},{"line_number":127,"context_line":"            reply \u003d self.client.delete(self._lock_url)"},{"line_number":128,"context_line":"            if reply.get(\"errorCode\") is None:"},{"line_number":129,"context_line":"                self.coord._acquired_locks.remove(self)"},{"line_number":130,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_38d3dbd6","line":127,"in_reply_to":"7a740942_ab278cc8","updated":"2015-12-08 16:55:35.000000000","message":"Just thinking of this scenario:\n\nCoordinator 1 using url XYZ:\n\n t0 \u003cgets lock\u003e\n t1 \u003csomeone unplugs network cable\u003e\n t2 \u003csomeone plugs network cable back in\u003e\n t3 \u003crelease lock happens\u003e\n\nCoordinator 2 using url XYZ:\n\n t1.5 \u003cgets lock\u003e\n t3.5 \u003crelease lock happens\u003e\n\nUsing the above time ordering who releases what?\n\nLet\u0027s also assume the lock ttl is low enough that between t1 and t2 etcd removes the key for simplicity (it doesn\u0027t really matter we can tweak this scenario to work with nearly any ttl).","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"dcf21db4a9fd5c55d5a348fac392750ce4aa29d4","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        if self in self.coord._acquired_locks:"},{"line_number":127,"context_line":"            reply \u003d self.client.delete(self._lock_url)"},{"line_number":128,"context_line":"            if reply.get(\"errorCode\") is None:"},{"line_number":129,"context_line":"                self.coord._acquired_locks.remove(self)"},{"line_number":130,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_a2b90d7b","line":127,"in_reply_to":"7a740942_e2c15555","updated":"2015-12-07 20:36:07.000000000","message":"Seems like https://coreos.com/etcd/docs/0.4.7/etcd-api/#atomic-compare-and-delete should be used right?","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"65d2f18b7fe351eaddf75f31ac4adef657583780","unresolved":false,"context_lines":[{"line_number":124,"context_line":"    @_translate_failures"},{"line_number":125,"context_line":"    def release(self):"},{"line_number":126,"context_line":"        if self in self.coord._acquired_locks:"},{"line_number":127,"context_line":"            reply \u003d self.client.delete(self._lock_url)"},{"line_number":128,"context_line":"            if reply.get(\"errorCode\") is None:"},{"line_number":129,"context_line":"                self.coord._acquired_locks.remove(self)"},{"line_number":130,"context_line":"                return True"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_ab278cc8","line":127,"in_reply_to":"7a740942_e2c15555","updated":"2015-12-08 10:29:57.000000000","message":"Why anyone? It only delete if the lock has been acquired by this coordinator. What do I miss?","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"e33688c0ab97d67c3795ab232394276dbf14cfea","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        \"\"\"Keep the lock alive.\"\"\""},{"line_number":136,"context_line":"        poked \u003d self.client.put(self._lock_url,"},{"line_number":137,"context_line":"                                data\u003d{\"ttl\": self.ttl,"},{"line_number":138,"context_line":"                                      \"prevExist\": \"true\"})"},{"line_number":139,"context_line":"        errorcode \u003d poked.get(\"errorCode\")"},{"line_number":140,"context_line":"        if errorcode:"},{"line_number":141,"context_line":"            LOG.warn(\"Unable to heartbeat by updating key \u0027%s\u0027 with extended\""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_c233f912","line":138,"updated":"2015-12-07 20:37:24.000000000","message":"Should this also use CAS to ensure that the entity doing the heartbeat actually has the lock still?","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"65d2f18b7fe351eaddf75f31ac4adef657583780","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        \"\"\"Keep the lock alive.\"\"\""},{"line_number":136,"context_line":"        poked \u003d self.client.put(self._lock_url,"},{"line_number":137,"context_line":"                                data\u003d{\"ttl\": self.ttl,"},{"line_number":138,"context_line":"                                      \"prevExist\": \"true\"})"},{"line_number":139,"context_line":"        errorcode \u003d poked.get(\"errorCode\")"},{"line_number":140,"context_line":"        if errorcode:"},{"line_number":141,"context_line":"            LOG.warn(\"Unable to heartbeat by updating key \u0027%s\u0027 with extended\""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_cb0bf828","line":138,"in_reply_to":"7a740942_c233f912","updated":"2015-12-08 10:29:57.000000000","message":"If you think there is a problem, we need to write more tests for all drivers for this kind of scenario at this stage.","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":6488,"name":"Clint Byrum","email":"clint@fewbar.com","username":"clint-fewbar"},"change_message_id":"9fa9c2660229c5b96ffc4b003a01f1178ca964e8","unresolved":false,"context_lines":[{"line_number":135,"context_line":"        \"\"\"Keep the lock alive.\"\"\""},{"line_number":136,"context_line":"        poked \u003d self.client.put(self._lock_url,"},{"line_number":137,"context_line":"                                data\u003d{\"ttl\": self.ttl,"},{"line_number":138,"context_line":"                                      \"prevExist\": \"true\"})"},{"line_number":139,"context_line":"        errorcode \u003d poked.get(\"errorCode\")"},{"line_number":140,"context_line":"        if errorcode:"},{"line_number":141,"context_line":"            LOG.warn(\"Unable to heartbeat by updating key \u0027%s\u0027 with extended\""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a740942_79d64550","line":138,"in_reply_to":"7a740942_cb0bf828","updated":"2015-12-08 17:38:35.000000000","message":"It\u0027s ok to reason about things and try hard to get things at least somewhat better without a test. Especially when talking about race conditions, which I covered in my previous comment.","commit_id":"8725b3d6c3f729141983ce0116fcefe51859b25b"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"2aa41c2ee377c24615de8040f6341f9043cf63f1","unresolved":false,"context_lines":[{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import httplib"},{"line_number":16,"context_line":"import logging"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_utils import timeutils"}],"source_content_type":"text/x-python","patch_set":9,"id":"7a740942_cc9c92c2","line":15,"updated":"2015-12-11 18:23:26.000000000","message":"It looks like you support Python 3, wouldn\u0027t it be better to import httplib/http.client from six instead?","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"3f98c091ea1c23f894a7216bfdf8fd84204cc8a3","unresolved":false,"context_lines":[{"line_number":12,"context_line":"# License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"# under the License."},{"line_number":14,"context_line":""},{"line_number":15,"context_line":"import httplib"},{"line_number":16,"context_line":"import logging"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_utils import timeutils"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_0fc15380","line":15,"in_reply_to":"7a740942_cc9c92c2","updated":"2015-12-18 10:00:01.000000000","message":"Done","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"2aa41c2ee377c24615de8040f6341f9043cf63f1","unresolved":false,"context_lines":[{"line_number":15,"context_line":"import httplib"},{"line_number":16,"context_line":"import logging"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_utils import timeutils"},{"line_number":19,"context_line":"import requests"},{"line_number":20,"context_line":"import six"},{"line_number":21,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"7a740942_89ad1c86","line":18,"updated":"2015-12-11 18:23:26.000000000","message":"Using oslo.utils but not oslo.log?","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"3f98c091ea1c23f894a7216bfdf8fd84204cc8a3","unresolved":false,"context_lines":[{"line_number":15,"context_line":"import httplib"},{"line_number":16,"context_line":"import logging"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from oslo_utils import timeutils"},{"line_number":19,"context_line":"import requests"},{"line_number":20,"context_line":"import six"},{"line_number":21,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_8f3b039c","line":18,"in_reply_to":"7a740942_89ad1c86","updated":"2015-12-18 10:00:01.000000000","message":"No, I don\u0027t see the need?","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"2aa41c2ee377c24615de8040f6341f9043cf63f1","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    def wrapper(*args, **kwargs):"},{"line_number":36,"context_line":"        try:"},{"line_number":37,"context_line":"            return func(*args, **kwargs)"},{"line_number":38,"context_line":"        except (requests.exceptions.RequestException,"},{"line_number":39,"context_line":"                httplib.HTTPException) as e:"},{"line_number":40,"context_line":"            coordination.raise_with_cause(coordination.ToozConnectionError,"},{"line_number":41,"context_line":"                                          utils.exception_message(e),"}],"source_content_type":"text/x-python","patch_set":9,"id":"7a740942_2918a874","line":38,"updated":"2015-12-11 18:23:26.000000000","message":"Also you use this tuple in a few places throughout this file, perhaps its best to give it a single name and refer to that elsewhere in the file, e.g.,\n\n    LOG \u003d logging.getLogger(__name__)\n    HTTPErrors \u003d (requests.exceptions.RequestException,\n                 httplib.HTTPException)\n\n\n    def _translate_failures(func):\n        # ...\n            try:\n                return func(*args, **kwargs)\n            except HTTPErrors as e:\n                coordination.raise_with_cause(...)","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"3f98c091ea1c23f894a7216bfdf8fd84204cc8a3","unresolved":false,"context_lines":[{"line_number":35,"context_line":"    def wrapper(*args, **kwargs):"},{"line_number":36,"context_line":"        try:"},{"line_number":37,"context_line":"            return func(*args, **kwargs)"},{"line_number":38,"context_line":"        except (requests.exceptions.RequestException,"},{"line_number":39,"context_line":"                httplib.HTTPException) as e:"},{"line_number":40,"context_line":"            coordination.raise_with_cause(coordination.ToozConnectionError,"},{"line_number":41,"context_line":"                                          utils.exception_message(e),"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_cf510bda","line":38,"in_reply_to":"7a740942_2918a874","updated":"2015-12-18 10:00:01.000000000","message":"Done","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"2aa41c2ee377c24615de8040f6341f9043cf63f1","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        try:"},{"line_number":37,"context_line":"            return func(*args, **kwargs)"},{"line_number":38,"context_line":"        except (requests.exceptions.RequestException,"},{"line_number":39,"context_line":"                httplib.HTTPException) as e:"},{"line_number":40,"context_line":"            coordination.raise_with_cause(coordination.ToozConnectionError,"},{"line_number":41,"context_line":"                                          utils.exception_message(e),"},{"line_number":42,"context_line":"                                          cause\u003de)"}],"source_content_type":"text/x-python","patch_set":9,"id":"7a740942_76af6f2a","line":39,"updated":"2015-12-11 18:23:26.000000000","message":"How\u0027re you getting an httplib error here?","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"f9116b565f6475a6fda7322608cf3428abdbd416","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        try:"},{"line_number":37,"context_line":"            return func(*args, **kwargs)"},{"line_number":38,"context_line":"        except (requests.exceptions.RequestException,"},{"line_number":39,"context_line":"                httplib.HTTPException) as e:"},{"line_number":40,"context_line":"            coordination.raise_with_cause(coordination.ToozConnectionError,"},{"line_number":41,"context_line":"                                          utils.exception_message(e),"},{"line_number":42,"context_line":"                                          cause\u003de)"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a7b0d38_6ebf8baa","line":39,"in_reply_to":"3a7e1126_ef21674e","updated":"2015-12-28 23:14:48.000000000","message":"What versions of requests are you seeing raise/allow httplib exceptions through and what exact requests are you seeing trigger those?","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"3f98c091ea1c23f894a7216bfdf8fd84204cc8a3","unresolved":false,"context_lines":[{"line_number":36,"context_line":"        try:"},{"line_number":37,"context_line":"            return func(*args, **kwargs)"},{"line_number":38,"context_line":"        except (requests.exceptions.RequestException,"},{"line_number":39,"context_line":"                httplib.HTTPException) as e:"},{"line_number":40,"context_line":"            coordination.raise_with_cause(coordination.ToozConnectionError,"},{"line_number":41,"context_line":"                                          utils.exception_message(e),"},{"line_number":42,"context_line":"                                          cause\u003de)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_ef21674e","line":39,"in_reply_to":"7a740942_76af6f2a","updated":"2015-12-18 10:00:01.000000000","message":"Requests can raise those.","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":12000,"name":"Ian Cordasco","email":"sigmavirus24@gmail.com","username":"sigmavirus24"},"change_message_id":"2aa41c2ee377c24615de8040f6341f9043cf63f1","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    def __init__(self, host, port, protocol):"},{"line_number":49,"context_line":"        self.host \u003d host"},{"line_number":50,"context_line":"        self.port \u003d port"},{"line_number":51,"context_line":"        self.protocol \u003d protocol"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @property"},{"line_number":54,"context_line":"    def base_url(self):"}],"source_content_type":"text/x-python","patch_set":9,"id":"7a740942_496ad4b4","line":51,"updated":"2015-12-11 18:23:26.000000000","message":"Why not maintain a session here and utilize thread-pooling?","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"3f98c091ea1c23f894a7216bfdf8fd84204cc8a3","unresolved":false,"context_lines":[{"line_number":48,"context_line":"    def __init__(self, host, port, protocol):"},{"line_number":49,"context_line":"        self.host \u003d host"},{"line_number":50,"context_line":"        self.port \u003d port"},{"line_number":51,"context_line":"        self.protocol \u003d protocol"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @property"},{"line_number":54,"context_line":"    def base_url(self):"}],"source_content_type":"text/x-python","patch_set":9,"id":"3a7e1126_0fe4f30a","line":51,"in_reply_to":"7a740942_496ad4b4","updated":"2015-12-18 10:00:01.000000000","message":"Done","commit_id":"ce2bdc357f605cf4f1aef3e6bc0a820ce6568b14"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"72114d70f2f02791b63bfce7224750e3f296234e","unresolved":false,"context_lines":[{"line_number":156,"context_line":"    DEFAULT_TIMEOUT \u003d 30"},{"line_number":157,"context_line":""},{"line_number":158,"context_line":"    def __init__(self, member_id, parsed_url, options):"},{"line_number":159,"context_line":"        super(EtcdDriver, self).__init__()"},{"line_number":160,"context_line":"        self.client \u003d _Client(host\u003dparsed_url.hostname,"},{"line_number":161,"context_line":"                              port\u003dparsed_url.port,"},{"line_number":162,"context_line":"                              protocol\u003doptions.get(\u0027protocol\u0027, \u0027http\u0027))"}],"source_content_type":"text/x-python","patch_set":14,"id":"1a7b0d38_37d5e642","line":159,"updated":"2015-12-23 00:20:36.000000000","message":"Pretty sure u need to call https://github.com/openstack/tooz/blob/master/tooz/utils.py#L131 if u want to access options like options.get(\"timeout\") or otherwise u have to do options.get(\"timeout\", [self.DEFAULT_TIMEOUT])[-1] and all that fun fun..","commit_id":"f9d9298808fe65c7d72da95527e21481b7fa48b4"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"dc8aa55a2661038c31e12d6e30ae8b8387d2ab79","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        self.ttl \u003d ttl"},{"line_number":84,"context_line":"        # NOTE(jd) sha1 of the name to be sure it works with any string?"},{"line_number":85,"context_line":"        self._lock_url \u003d ("},{"line_number":86,"context_line":"            \"/keys/\" + self._TOOZ_LOCK_PREFIX + \"/\" + name.decode(\u0027ascii\u0027)"},{"line_number":87,"context_line":"        )"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def acquire(self, blocking\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a7b0d38_92dcbae5","line":86,"updated":"2015-12-24 03:17:56.000000000","message":"More likely a urlencode right?","commit_id":"a4bb52513566660ba5d5b801fae5ec128b3cea1f"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"2792dd9897327533a40ff520f0cd1f7e43d7b024","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        self.ttl \u003d ttl"},{"line_number":84,"context_line":"        # NOTE(jd) sha1 of the name to be sure it works with any string?"},{"line_number":85,"context_line":"        self._lock_url \u003d ("},{"line_number":86,"context_line":"            \"/keys/\" + self._TOOZ_LOCK_PREFIX + \"/\" + name.decode(\u0027ascii\u0027)"},{"line_number":87,"context_line":"        )"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def acquire(self, blocking\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a7b0d38_2de6b2b4","line":86,"in_reply_to":"1a7b0d38_34aeff85","updated":"2015-12-24 18:31:29.000000000","message":"Ya, good point, or names that are really really long...","commit_id":"a4bb52513566660ba5d5b801fae5ec128b3cea1f"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"fbb31954b367188ef950188a1f20dfc2137d82c2","unresolved":false,"context_lines":[{"line_number":83,"context_line":"        self.ttl \u003d ttl"},{"line_number":84,"context_line":"        # NOTE(jd) sha1 of the name to be sure it works with any string?"},{"line_number":85,"context_line":"        self._lock_url \u003d ("},{"line_number":86,"context_line":"            \"/keys/\" + self._TOOZ_LOCK_PREFIX + \"/\" + name.decode(\u0027ascii\u0027)"},{"line_number":87,"context_line":"        )"},{"line_number":88,"context_line":""},{"line_number":89,"context_line":"    def acquire(self, blocking\u003dTrue):"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a7b0d38_34aeff85","line":86,"in_reply_to":"1a7b0d38_92dcbae5","updated":"2015-12-24 15:51:59.000000000","message":"Not sure i\u0027d be enough to solve the case of \u0027/\u0027 for example.","commit_id":"a4bb52513566660ba5d5b801fae5ec128b3cea1f"},{"author":{"_account_id":1297,"name":"Joshua Harlow","email":"jxharlow@godaddy.com","username":"harlowja"},"change_message_id":"dc8aa55a2661038c31e12d6e30ae8b8387d2ab79","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                    data\u003d{\"ttl\": self.ttl,"},{"line_number":102,"context_line":"                          \"prevExist\": \"false\"})"},{"line_number":103,"context_line":"            except HTTPErrors:"},{"line_number":104,"context_line":"                if watch and watch.leftover() \u003d\u003d 0:"},{"line_number":105,"context_line":"                    return False"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"            # We got the lock!"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a7b0d38_72e10e9a","line":104,"updated":"2015-12-24 03:17:56.000000000","message":"watch.expired() will avoid this \u003d\u003d zero check, just fyi","commit_id":"a4bb52513566660ba5d5b801fae5ec128b3cea1f"},{"author":{"_account_id":1669,"name":"Julien Danjou","display_name":"jd","email":"julien@danjou.info","username":"jdanjou"},"change_message_id":"fbb31954b367188ef950188a1f20dfc2137d82c2","unresolved":false,"context_lines":[{"line_number":101,"context_line":"                    data\u003d{\"ttl\": self.ttl,"},{"line_number":102,"context_line":"                          \"prevExist\": \"false\"})"},{"line_number":103,"context_line":"            except HTTPErrors:"},{"line_number":104,"context_line":"                if watch and watch.leftover() \u003d\u003d 0:"},{"line_number":105,"context_line":"                    return False"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"            # We got the lock!"}],"source_content_type":"text/x-python","patch_set":15,"id":"1a7b0d38_34c59f3b","line":104,"in_reply_to":"1a7b0d38_72e10e9a","updated":"2015-12-24 15:51:59.000000000","message":"Done","commit_id":"a4bb52513566660ba5d5b801fae5ec128b3cea1f"}]}
