)]}'
{"doc/saio/rsyncd.conf":[{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"d12015775cd10c454dd553b90f29d76c82f47611","unresolved":false,"context_lines":[{"line_number":1,"context_line":"uid \u003d \u003cyour-user-name\u003e"},{"line_number":2,"context_line":"gid \u003d \u003cyour-user-name\u003e"},{"line_number":3,"context_line":"pid file \u003d /var/run/rsyncd.pid"},{"line_number":4,"context_line":"syslog facility \u003d local7"},{"line_number":5,"context_line":"address \u003d 0.0.0.0"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"[account6012]"}],"source_content_type":"text/plain","patch_set":3,"id":"5f7c97a3_d8d4fabf","line":4,"updated":"2018-05-09 21:38:31.000000000","message":"Why does this have to be a part of sharding patch?","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1,"context_line":"uid \u003d \u003cyour-user-name\u003e"},{"line_number":2,"context_line":"gid \u003d \u003cyour-user-name\u003e"},{"line_number":3,"context_line":"pid file \u003d /var/run/rsyncd.pid"},{"line_number":4,"context_line":"syslog facility \u003d local7"},{"line_number":5,"context_line":"address \u003d 0.0.0.0"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"[account6012]"}],"source_content_type":"text/plain","patch_set":3,"id":"5f7c97a3_0c6470b8","line":4,"in_reply_to":"5f7c97a3_d8d4fabf","updated":"2018-05-10 22:58:32.000000000","message":"Came as part of running down the failing probe tests in https://review.openstack.org/#/c/550291/ -- I was trying to get any extra information I could. Probably not necessary, but maybe still useful for debugging check failures?\n\nIn case you\u0027re curious, the problem was eventually fixed with https://review.openstack.org/#/c/550291/15..16/swift/container/sharder.py","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d9da0116d5655995a7045fcbf71d64cddc19fd08","unresolved":false,"context_lines":[{"line_number":1,"context_line":"uid \u003d \u003cyour-user-name\u003e"},{"line_number":2,"context_line":"gid \u003d \u003cyour-user-name\u003e"},{"line_number":3,"context_line":"pid file \u003d /var/run/rsyncd.pid"},{"line_number":4,"context_line":"syslog facility \u003d local7"},{"line_number":5,"context_line":"address \u003d 0.0.0.0"},{"line_number":6,"context_line":""},{"line_number":7,"context_line":"[account6012]"}],"source_content_type":"text/plain","patch_set":3,"id":"5f7c97a3_9ab3c90a","line":4,"in_reply_to":"5f7c97a3_d8d4fabf","updated":"2018-05-10 11:21:34.000000000","message":"must have crept in from early testing. I will remove.","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"}],"swift/account/backend.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":233,"context_line":"        with self.get() as conn:"},{"line_number":234,"context_line":"            row \u003d conn.execute("},{"line_number":235,"context_line":"                \u0027SELECT container_count from account_stat\u0027).fetchone()"},{"line_number":236,"context_line":"            return zero_like(row[0])"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def make_tuple_for_pickle(self, record):"},{"line_number":239,"context_line":"        return (record[\u0027name\u0027], record[\u0027put_timestamp\u0027],"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_3fe74215","line":236,"range":{"start_line":236,"start_character":19,"end_line":236,"end_character":36},"updated":"2018-05-08 10:11:34.000000000","message":"Hmm... this increase the acceptable status more than the original code (from only 0 to zero_like). container_count is INTEGER and 0 at the init so i don\u0027t think it would be zero_like value...\n\nExactly zero_like covers row[0] \u003d\u003d 0 case tho.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":233,"context_line":"        with self.get() as conn:"},{"line_number":234,"context_line":"            row \u003d conn.execute("},{"line_number":235,"context_line":"                \u0027SELECT container_count from account_stat\u0027).fetchone()"},{"line_number":236,"context_line":"            return zero_like(row[0])"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def make_tuple_for_pickle(self, record):"},{"line_number":239,"context_line":"        return (record[\u0027name\u0027], record[\u0027put_timestamp\u0027],"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_ebd58844","line":236,"range":{"start_line":236,"start_character":19,"end_line":236,"end_character":36},"in_reply_to":"5f7c97a3_3fe74215","updated":"2018-05-08 12:44:19.000000000","message":"Clay added the zero_like helper to get consistency, I think, for example compared with line 257. Yes, the allowed value set expands here but I think it is ok?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":233,"context_line":"        with self.get() as conn:"},{"line_number":234,"context_line":"            row \u003d conn.execute("},{"line_number":235,"context_line":"                \u0027SELECT container_count from account_stat\u0027).fetchone()"},{"line_number":236,"context_line":"            return zero_like(row[0])"},{"line_number":237,"context_line":""},{"line_number":238,"context_line":"    def make_tuple_for_pickle(self, record):"},{"line_number":239,"context_line":"        return (record[\u0027name\u0027], record[\u0027put_timestamp\u0027],"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_f5cb146f","line":236,"range":{"start_line":236,"start_character":19,"end_line":236,"end_character":36},"in_reply_to":"5f7c97a3_ebd58844","updated":"2018-05-09 11:33:49.000000000","message":"Probably no problem, I think. Because I\u0027m not an expert of sqlite so just I was wondering if row[0] can take zero like value (e.g. \u0027\u0027, None) for any unexpected cases.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":273,"context_line":""},{"line_number":274,"context_line":"        :returns: True if the DB is considered to be deleted, False otherwise"},{"line_number":275,"context_line":"        \"\"\""},{"line_number":276,"context_line":"        return status \u003d\u003d \u0027DELETED\u0027 or zero_like(container_count) and ("},{"line_number":277,"context_line":"            Timestamp(delete_timestamp) \u003e Timestamp(put_timestamp))"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _is_deleted(self, conn):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_daff3cff","line":276,"updated":"2018-05-08 10:11:34.000000000","message":"I was worried a bit about this changes the place of brackets but it seems still fine to me.\n\nzero_like should return bool so all states should be bools.\n\nThen, i recheck the python behavior briefly, like:\n\n\u003e\u003e\u003e False or False and True\nFalse\n\u003e\u003e\u003e False or True and False\nFalse\n\u003e\u003e\u003e False or True and True\nTrue\n\u003e\u003e\u003e True or False and False\nTrue\n\nThat makes me sense, this will be True when the first one is True or both the latter states are True.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":273,"context_line":""},{"line_number":274,"context_line":"        :returns: True if the DB is considered to be deleted, False otherwise"},{"line_number":275,"context_line":"        \"\"\""},{"line_number":276,"context_line":"        return status \u003d\u003d \u0027DELETED\u0027 or zero_like(container_count) and ("},{"line_number":277,"context_line":"            Timestamp(delete_timestamp) \u003e Timestamp(put_timestamp))"},{"line_number":278,"context_line":""},{"line_number":279,"context_line":"    def _is_deleted(self, conn):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_0bc0047b","line":276,"in_reply_to":"5f7c97a3_daff3cff","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        return zero_like(info[\u0027container_count\u0027]) and ("},{"line_number":308,"context_line":"            Timestamp(now - reclaim_age) \u003e"},{"line_number":309,"context_line":"            Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":310,"context_line":"            Timestamp(info[\u0027put_timestamp\u0027]))"},{"line_number":311,"context_line":""},{"line_number":312,"context_line":"    def get_policy_stats(self, do_migrations\u003dFalse):"},{"line_number":313,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_9a09c42d","line":310,"updated":"2018-05-08 10:11:34.000000000","message":"My own memo) Where does this come from?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        return zero_like(info[\u0027container_count\u0027]) and ("},{"line_number":308,"context_line":"            Timestamp(now - reclaim_age) \u003e"},{"line_number":309,"context_line":"            Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":310,"context_line":"            Timestamp(info[\u0027put_timestamp\u0027]))"},{"line_number":311,"context_line":""},{"line_number":312,"context_line":"    def get_policy_stats(self, do_migrations\u003dFalse):"},{"line_number":313,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_557a08f1","line":310,"in_reply_to":"5f7c97a3_4b74bc68","updated":"2018-05-09 11:33:49.000000000","message":"Oh, thanks for the response to my own memo.\nThat makes me sense to know the nice encapsulation. Though it would be expected to reduce \"SELECT everything\", just self.get_info() call may be reusable to simplify the code.\n\n--- a/swift/account/backend.py\n+++ b/swift/account/backend.py\n@@ -299,11 +299,7 @@ class AccountBroker(DatabaseBroker):\n                 row[\u0027delete_timestamp\u0027] \u003e row[\u0027put_timestamp\u0027])\n \n     def is_reclaimable(self, now, reclaim_age):\n-        self._commit_puts_stale_ok()\n-        with self.get() as conn:\n-            info \u003d conn.execute(\u0027\u0027\u0027\n-                SELECT put_timestamp, delete_timestamp, container_count\n-                FROM account_stat\u0027\u0027\u0027).fetchone()\n+        info \u003d self.get_info()\n         return zero_like(info[\u0027container_count\u0027]) and (\n             Timestamp(now - reclaim_age) \u003e\n             Timestamp(info[\u0027delete_timestamp\u0027]) \u003e","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        return zero_like(info[\u0027container_count\u0027]) and ("},{"line_number":308,"context_line":"            Timestamp(now - reclaim_age) \u003e"},{"line_number":309,"context_line":"            Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":310,"context_line":"            Timestamp(info[\u0027put_timestamp\u0027]))"},{"line_number":311,"context_line":""},{"line_number":312,"context_line":"    def get_policy_stats(self, do_migrations\u003dFalse):"},{"line_number":313,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_3485055b","line":310,"in_reply_to":"5f7c97a3_557a08f1","updated":"2018-05-09 14:39:21.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":307,"context_line":"        return zero_like(info[\u0027container_count\u0027]) and ("},{"line_number":308,"context_line":"            Timestamp(now - reclaim_age) \u003e"},{"line_number":309,"context_line":"            Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":310,"context_line":"            Timestamp(info[\u0027put_timestamp\u0027]))"},{"line_number":311,"context_line":""},{"line_number":312,"context_line":"    def get_policy_stats(self, do_migrations\u003dFalse):"},{"line_number":313,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_4b74bc68","line":310,"in_reply_to":"5f7c97a3_9a09c42d","updated":"2018-05-08 12:44:19.000000000","message":"this change came in here https://review.openstack.org/#/c/561091/5/swift/common/db_replicator.py@587 to better encapsulate the conditions when a db should be reclaimed.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"}],"swift/common/db.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":71,"context_line":"            metadata[k.decode(\u0027utf-8\u0027)] \u003d sv"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"ZERO_LIKE_VALUES \u003d set((None, \u0027\u0027, 0, \u00270\u0027))"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def zero_like(count):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_da289c87","line":74,"range":{"start_line":74,"start_character":19,"end_line":74,"end_character":42},"updated":"2018-05-08 10:11:34.000000000","message":"nits) {None, \u0027\u0027, 0, \u00270\u0027}","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":71,"context_line":"            metadata[k.decode(\u0027utf-8\u0027)] \u003d sv"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"ZERO_LIKE_VALUES \u003d set((None, \u0027\u0027, 0, \u00270\u0027))"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def zero_like(count):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_eb0828da","line":74,"range":{"start_line":74,"start_character":19,"end_line":74,"end_character":42},"in_reply_to":"5f7c97a3_da289c87","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":317,"context_line":"            with open(tmp_db_file, \u0027r+b\u0027) as fp:"},{"line_number":318,"context_line":"                os.fsync(fp.fileno())"},{"line_number":319,"context_line":"            with lock_parent_directory(self.db_file, self.pending_timeout):"},{"line_number":320,"context_line":"                if self._db_exists():"},{"line_number":321,"context_line":"                    # It\u0027s as if there was a \"condition\" where different parts"},{"line_number":322,"context_line":"                    # of the system were \"racing\" each other."},{"line_number":323,"context_line":"                    raise DatabaseAlreadyExists(self.db_file)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_6c69c823","line":320,"updated":"2018-05-08 00:03:33.000000000","message":"Right, no change from before on account of the `if tmp_db_file` above.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":317,"context_line":"            with open(tmp_db_file, \u0027r+b\u0027) as fp:"},{"line_number":318,"context_line":"                os.fsync(fp.fileno())"},{"line_number":319,"context_line":"            with lock_parent_directory(self.db_file, self.pending_timeout):"},{"line_number":320,"context_line":"                if self._db_exists():"},{"line_number":321,"context_line":"                    # It\u0027s as if there was a \"condition\" where different parts"},{"line_number":322,"context_line":"                    # of the system were \"racing\" each other."},{"line_number":323,"context_line":"                    raise DatabaseAlreadyExists(self.db_file)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_90b8c576","line":320,"in_reply_to":"5f7c97a3_6c69c823","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    @property"},{"line_number":349,"context_line":"    def db_file(self):"},{"line_number":350,"context_line":"        return self._db_file"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def _create_connection(self, db_file\u003dNone):"},{"line_number":353,"context_line":"        if not db_file:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_5a980cbf","line":350,"updated":"2018-05-08 10:11:34.000000000","message":"Maybe this is for protection of the db_file instance value but not sure, we may touch the value in the future parts in the deep-review patch chain...","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    @property"},{"line_number":349,"context_line":"    def db_file(self):"},{"line_number":350,"context_line":"        return self._db_file"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def _create_connection(self, db_file\u003dNone):"},{"line_number":353,"context_line":"        if not db_file:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_cb2e8c42","line":350,"in_reply_to":"5f7c97a3_5a980cbf","updated":"2018-05-08 12:44:19.000000000","message":"this will make more sense later in patch chain where the definition of db_file is overridden for ContainerBroker\n\nhttps://review.openstack.org/#/c/565744/2/swift/container/backend.py@403","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    @property"},{"line_number":349,"context_line":"    def db_file(self):"},{"line_number":350,"context_line":"        return self._db_file"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def _create_connection(self, db_file\u003dNone):"},{"line_number":353,"context_line":"        if not db_file:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_d54b7828","line":350,"in_reply_to":"5f7c97a3_cb2e8c42","updated":"2018-05-09 11:33:49.000000000","message":"Got it. The reflection would be overwritten by child class.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":349,"context_line":"    def db_file(self):"},{"line_number":350,"context_line":"        return self._db_file"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def _create_connection(self, db_file\u003dNone):"},{"line_number":353,"context_line":"        if not db_file:"},{"line_number":354,"context_line":"            db_file \u003d self.db_file"},{"line_number":355,"context_line":"        if self.db_file \u003d\u003d \u0027:memory:\u0027:"},{"line_number":356,"context_line":"            return"},{"line_number":357,"context_line":"        try:"},{"line_number":358,"context_line":"            self.conn \u003d get_db_connection(db_file, self.timeout)"},{"line_number":359,"context_line":"        except (sqlite3.DatabaseError, DatabaseConnectionError):"},{"line_number":360,"context_line":"            self.possibly_quarantine(*sys.exc_info())"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"    def get_device_path(self):"},{"line_number":363,"context_line":"        prefix_path \u003d os.path.dirname(self.db_dir)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_fae0f8ce","line":360,"range":{"start_line":352,"start_character":0,"end_line":360,"end_character":53},"updated":"2018-05-08 10:11:34.000000000","message":"Hmm... I\u0027m not sure if this method is really needed or not.\n\nThe reason is A) nowhere this is called in this patch, B) even in the last patch of the chain (i.e. 565749), C) the only place calling this is in the unit testing with the db_file arg as below.\n\n yukimura:swift tsuyuzaki$ egrep _create_connection * -R\n swift/common/db.py:    def _create_connection(self, db_file\u003dNone):\n Binary file swift/common/db.pyc matches\n test/unit/container/test_backend.py:        \n broker._create_connection(broker._db_file)\n\nPlus,  the line 355 looks brittle a bit because it doesn\u0027t care of the case setting \u0027:memory:\u0027 to the db_file argument. Perhaps,\n\n if db_file \u003d\u003d \u0027:memory:\u0027:\n   return\n\nmight be better? However, I\u0027m still not sure because the caller is only one unit test case so I cannot decide what\u0027s expected for this method for now.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":349,"context_line":"    def db_file(self):"},{"line_number":350,"context_line":"        return self._db_file"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def _create_connection(self, db_file\u003dNone):"},{"line_number":353,"context_line":"        if not db_file:"},{"line_number":354,"context_line":"            db_file \u003d self.db_file"},{"line_number":355,"context_line":"        if self.db_file \u003d\u003d \u0027:memory:\u0027:"},{"line_number":356,"context_line":"            return"},{"line_number":357,"context_line":"        try:"},{"line_number":358,"context_line":"            self.conn \u003d get_db_connection(db_file, self.timeout)"},{"line_number":359,"context_line":"        except (sqlite3.DatabaseError, DatabaseConnectionError):"},{"line_number":360,"context_line":"            self.possibly_quarantine(*sys.exc_info())"},{"line_number":361,"context_line":""},{"line_number":362,"context_line":"    def get_device_path(self):"},{"line_number":363,"context_line":"        prefix_path \u003d os.path.dirname(self.db_dir)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_ab86b0da","line":360,"range":{"start_line":352,"start_character":0,"end_line":360,"end_character":53},"in_reply_to":"5f7c97a3_fae0f8ce","updated":"2018-05-08 12:44:19.000000000","message":"good catch - I don\u0027t think the method is required, the use in test case if for a sanity check and can be handled differently. I will delete this.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":411,"context_line":"        self.quarantine(exc_hint)"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    @contextmanager"},{"line_number":414,"context_line":"    def updated_timeout(self, new_timeout):"},{"line_number":415,"context_line":"        \"\"\"Use with \"with\" statement; updates ``timeout`` within the block.\"\"\""},{"line_number":416,"context_line":"        old_timeout \u003d self.timeout"},{"line_number":417,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_553c5fc7","line":414,"updated":"2018-05-08 10:11:34.000000000","message":"Hmm... this looks to be used by manage_shard_ranges.py in the latter patch set to support different timeout either replace or enable. My pure question is why we don\u0027t initiate the DB Broker for each time. Not sure if it has super overhead to open, yet. If it\u0027s acceptable to set the timeout to initialize the DBBroker, we don\u0027t need this hacky change, do it?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":411,"context_line":"        self.quarantine(exc_hint)"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    @contextmanager"},{"line_number":414,"context_line":"    def updated_timeout(self, new_timeout):"},{"line_number":415,"context_line":"        \"\"\"Use with \"with\" statement; updates ``timeout`` within the block.\"\"\""},{"line_number":416,"context_line":"        old_timeout \u003d self.timeout"},{"line_number":417,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_ebc108e6","line":414,"in_reply_to":"5f7c97a3_553c5fc7","updated":"2018-05-08 12:44:19.000000000","message":"Tim added this here [1]. I guess it wouldn\u0027t be too hard to clone a broker instance. Let\u0027s see if Tim gets chance to respond.\n\n[1] https://review.openstack.org/#/c/560772/","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":411,"context_line":"        self.quarantine(exc_hint)"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    @contextmanager"},{"line_number":414,"context_line":"    def updated_timeout(self, new_timeout):"},{"line_number":415,"context_line":"        \"\"\"Use with \"with\" statement; updates ``timeout`` within the block.\"\"\""},{"line_number":416,"context_line":"        old_timeout \u003d self.timeout"},{"line_number":417,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_9503c0b8","line":414,"in_reply_to":"5f7c97a3_5986c8dd","updated":"2018-05-09 11:33:49.000000000","message":"To consider if we need this staff, I\u0027m feeling I should go ahead to later patches, what\u0027s changed around the DB broker. In my understanding, DB broker can be just a connector and should not much keep its internal state in memory as possible so just I thought an initiation would be nice to be simple at a time when we want a new DB broker instance with different configuration but container sharding would change the roles a bit to manage both local sqlite db and sharding state.\n\nI\u0027ll circle back here to say something later. Thanks Alistair and Tim for the response.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71e233b3759b3f4ef6374145764883e49a2c618d","unresolved":false,"context_lines":[{"line_number":411,"context_line":"        self.quarantine(exc_hint)"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    @contextmanager"},{"line_number":414,"context_line":"    def updated_timeout(self, new_timeout):"},{"line_number":415,"context_line":"        \"\"\"Use with \"with\" statement; updates ``timeout`` within the block.\"\"\""},{"line_number":416,"context_line":"        old_timeout \u003d self.timeout"},{"line_number":417,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_65113704","line":414,"in_reply_to":"5f7c97a3_9503c0b8","updated":"2018-05-14 11:30:07.000000000","message":"tracking here https://trello.com/c/qU7nzcHy","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"13b32417a72c0ddf4c5f9328489285b0635ecd76","unresolved":false,"context_lines":[{"line_number":411,"context_line":"        self.quarantine(exc_hint)"},{"line_number":412,"context_line":""},{"line_number":413,"context_line":"    @contextmanager"},{"line_number":414,"context_line":"    def updated_timeout(self, new_timeout):"},{"line_number":415,"context_line":"        \"\"\"Use with \"with\" statement; updates ``timeout`` within the block.\"\"\""},{"line_number":416,"context_line":"        old_timeout \u003d self.timeout"},{"line_number":417,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_5986c8dd","line":414,"in_reply_to":"5f7c97a3_ebc108e6","updated":"2018-05-08 23:17:01.000000000","message":"My main concern had to do with us doing a lot of work then throwing it all away because we hit a lock timeout trying to write down the fact that we made progress. Since I know this is a DB under a lot of contention and I\u0027m already worrying about timeouts, I figured it\u0027d be better to temporarily bump the timeout and keep all my broker state rather than reinitialize, but I also haven\u0027t looked deeply at how much overhead that involves (I just assumed it\u0027d be non-zero, and this didn\u0027t feel *so* hacky to me).","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":518,"context_line":""},{"line_number":519,"context_line":"        :returns: True if the DB is considered to be deleted, False otherwise"},{"line_number":520,"context_line":"        \"\"\""},{"line_number":521,"context_line":"        if self.db_file !\u003d \u0027:memory:\u0027 and not self._db_exists():"},{"line_number":522,"context_line":"            return True"},{"line_number":523,"context_line":"        self._commit_puts_stale_ok()"},{"line_number":524,"context_line":"        with self.get() as conn:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_6cd788c1","line":521,"range":{"start_line":521,"start_character":11,"end_line":521,"end_character":41},"updated":"2018-05-08 00:03:33.000000000","message":"Not strictly necessary -- `not self._db_exists()` implies `self.db_file !\u003d \u0027:memory:\u0027`","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":518,"context_line":""},{"line_number":519,"context_line":"        :returns: True if the DB is considered to be deleted, False otherwise"},{"line_number":520,"context_line":"        \"\"\""},{"line_number":521,"context_line":"        if self.db_file !\u003d \u0027:memory:\u0027 and not self._db_exists():"},{"line_number":522,"context_line":"            return True"},{"line_number":523,"context_line":"        self._commit_puts_stale_ok()"},{"line_number":524,"context_line":"        with self.get() as conn:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_f04fb98f","line":521,"range":{"start_line":521,"start_character":11,"end_line":521,"end_character":41},"in_reply_to":"5f7c97a3_6cd788c1","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":628,"context_line":"            FROM SQLITE_SEQUENCE"},{"line_number":629,"context_line":"            WHERE SQLITE_SEQUENCE.name \u003d\u003d \u0027%s\u0027"},{"line_number":630,"context_line":"            LIMIT 1"},{"line_number":631,"context_line":"        \u0027\u0027\u0027 % (table)"},{"line_number":632,"context_line":"        with self.get() as conn:"},{"line_number":633,"context_line":"            row \u003d conn.execute(query).fetchone()"},{"line_number":634,"context_line":"        return row[0] if row else -1"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_2ce1909b","line":631,"range":{"start_line":631,"start_character":14,"end_line":631,"end_character":21},"updated":"2018-05-08 00:03:33.000000000","message":"Not on you, but -- a little better as\n\n (table, )","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":628,"context_line":"            FROM SQLITE_SEQUENCE"},{"line_number":629,"context_line":"            WHERE SQLITE_SEQUENCE.name \u003d\u003d \u0027%s\u0027"},{"line_number":630,"context_line":"            LIMIT 1"},{"line_number":631,"context_line":"        \u0027\u0027\u0027 % (table)"},{"line_number":632,"context_line":"        with self.get() as conn:"},{"line_number":633,"context_line":"            row \u003d conn.execute(query).fetchone()"},{"line_number":634,"context_line":"        return row[0] if row else -1"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_102fd5a1","line":631,"range":{"start_line":631,"start_character":14,"end_line":631,"end_character":21},"in_reply_to":"5f7c97a3_2ce1909b","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":661,"context_line":"            return"},{"line_number":662,"context_line":"        if not self._db_exists():"},{"line_number":663,"context_line":"            raise DatabaseConnectionError(self.db_file, \"DB doesn\u0027t exist\")"},{"line_number":664,"context_line":"        if self.skip_commits:"},{"line_number":665,"context_line":"            raise DatabaseConnectionError(self.db_file, \"commits not accepted\")"},{"line_number":666,"context_line":"        with lock_parent_directory(self.pending_file, self.pending_timeout):"},{"line_number":667,"context_line":"            pending_size \u003d 0"},{"line_number":668,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_557e9f19","line":665,"range":{"start_line":664,"start_character":0,"end_line":665,"end_character":79},"updated":"2018-05-08 10:11:34.000000000","message":"Is this expected? I didn\u0027t get what module should be responsible for the DatabaseConnectionError. If we comment out those 2 lines, _commit_puts can skip the db commit for pending file. Am I missing something?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":661,"context_line":"            return"},{"line_number":662,"context_line":"        if not self._db_exists():"},{"line_number":663,"context_line":"            raise DatabaseConnectionError(self.db_file, \"DB doesn\u0027t exist\")"},{"line_number":664,"context_line":"        if self.skip_commits:"},{"line_number":665,"context_line":"            raise DatabaseConnectionError(self.db_file, \"commits not accepted\")"},{"line_number":666,"context_line":"        with lock_parent_directory(self.pending_file, self.pending_timeout):"},{"line_number":667,"context_line":"            pending_size \u003d 0"},{"line_number":668,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_2b229fa5","line":665,"range":{"start_line":664,"start_character":0,"end_line":665,"end_character":79},"in_reply_to":"5f7c97a3_557e9f19","updated":"2018-05-08 12:44:19.000000000","message":"This was added here [1]\n\nOn reflection this check is not necessary. At the time I expect I wanted to see an exception if put_record was ever called on a broker that was supposedly read-only, but the real goal was to never *commit* puts from the pending file. It is unexpected but harmless for a record to be written to the pending file via a broker with skip_commits\u003dTrue.\n\nI will remove the check.\n\n[1] https://review.openstack.org/#/c/558625","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":250,"context_line":"        The storage_policy_index is passed through to the subclass\u0027s"},{"line_number":251,"context_line":"        ``_initialize`` method.  It is ignored by ``AccountBroker``."},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"        :param put_timestamp: internalized timestamp of initial PUT request"},{"line_number":254,"context_line":"        :param storage_policy_index: only required for containers"},{"line_number":255,"context_line":"        \"\"\""},{"line_number":256,"context_line":"        if self._db_file \u003d\u003d \u0027:memory:\u0027:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_004a077f","line":253,"updated":"2018-05-09 11:33:49.000000000","message":"off-topic: I incline that I like to add small docs the put_timestamp is expected as Timestamp.internal string format when I was walking through the test_backend changes.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"d12015775cd10c454dd553b90f29d76c82f47611","unresolved":false,"context_lines":[{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    @property"},{"line_number":349,"context_line":"    def db_file(self):"},{"line_number":350,"context_line":"        return self._db_file"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def get_device_path(self):"},{"line_number":353,"context_line":"        prefix_path \u003d os.path.dirname(self.db_dir)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_1bc02c50","line":350,"updated":"2018-05-09 21:38:31.000000000","message":"You know, it\u0027s not that hard to change to _db_file everywhere, so you don\u0027t need the getter. This review does just that, among other things:\n\nhttps://review.openstack.org/47713","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84af3b7a5f814809ad669de45a5217dd65ea3925","unresolved":false,"context_lines":[{"line_number":347,"context_line":""},{"line_number":348,"context_line":"    @property"},{"line_number":349,"context_line":"    def db_file(self):"},{"line_number":350,"context_line":"        return self._db_file"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def get_device_path(self):"},{"line_number":353,"context_line":"        prefix_path \u003d os.path.dirname(self.db_dir)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_ae6f6bfa","line":350,"in_reply_to":"5f7c97a3_1bc02c50","updated":"2018-05-10 11:20:52.000000000","message":"The significance of the db_file property becomes apparent in a later patch [1]. Sorry, this change being non-obvious here is an example of the trade-off between breaking the changes down into a chain vs. one huge patch.\n\nhttps://review.openstack.org/#/c/565744/4/swift/container/backend.py@403","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":71,"context_line":"            metadata[k.decode(\u0027utf-8\u0027)] \u003d sv"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"ZERO_LIKE_VALUES \u003d {None, \u0027\u0027, 0, \u00270\u0027}"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def zero_like(count):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_bc49d731","line":74,"updated":"2018-05-10 22:58:32.000000000","message":"A bit out of scope, but is it worth including 0.0 and \u00270.0\u0027? Do we ever store floats?\n\nWhat about \u00270000000000.00000\u0027 or \u00270000000000.00000_0000000000000000\u0027?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d57fac29389a2cdae651fa42ba581775a7a6ac64","unresolved":false,"context_lines":[{"line_number":71,"context_line":"            metadata[k.decode(\u0027utf-8\u0027)] \u003d sv"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"ZERO_LIKE_VALUES \u003d {None, \u0027\u0027, 0, \u00270\u0027}"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def zero_like(count):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_123ea18a","line":74,"in_reply_to":"5f7c97a3_b5c7a596","updated":"2018-05-11 19:48:44.000000000","message":"Or, y\u0027know, don\u0027t worry about it.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":71,"context_line":"            metadata[k.decode(\u0027utf-8\u0027)] \u003d sv"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"ZERO_LIKE_VALUES \u003d {None, \u0027\u0027, 0, \u00270\u0027}"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"def zero_like(count):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_b5c7a596","line":74,"in_reply_to":"5f7c97a3_bc49d731","updated":"2018-05-11 14:26:48.000000000","message":"follow up","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":350,"context_line":"        return self._db_file"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def get_device_path(self):"},{"line_number":353,"context_line":"        prefix_path \u003d os.path.dirname(self.db_dir)"},{"line_number":354,"context_line":"        partition_path \u003d os.path.dirname(prefix_path)"},{"line_number":355,"context_line":"        dbs_path \u003d os.path.dirname(partition_path)"},{"line_number":356,"context_line":"        return os.path.dirname(dbs_path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_532c36ab","line":353,"range":{"start_line":353,"start_character":8,"end_line":353,"end_character":19},"updated":"2018-05-10 22:58:32.000000000","message":"Pre-existing, but... \"prefix\", or \"suffix\"?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":350,"context_line":"        return self._db_file"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def get_device_path(self):"},{"line_number":353,"context_line":"        prefix_path \u003d os.path.dirname(self.db_dir)"},{"line_number":354,"context_line":"        partition_path \u003d os.path.dirname(prefix_path)"},{"line_number":355,"context_line":"        dbs_path \u003d os.path.dirname(partition_path)"},{"line_number":356,"context_line":"        return os.path.dirname(dbs_path)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_b5756566","line":353,"range":{"start_line":353,"start_character":8,"end_line":353,"end_character":19},"in_reply_to":"5f7c97a3_532c36ab","updated":"2018-05-11 14:26:48.000000000","message":"Done. suffix_path would be consistent with rest of method","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"113e08d0319b98274ef945218aa2e46d3380d852","unresolved":false,"context_lines":[{"line_number":408,"context_line":"            self.timeout \u003d new_timeout"},{"line_number":409,"context_line":"            if self.conn:"},{"line_number":410,"context_line":"                self.conn.timeout \u003d new_timeout"},{"line_number":411,"context_line":"            yield old_timeout"},{"line_number":412,"context_line":"        finally:"},{"line_number":413,"context_line":"            self.timeout \u003d old_timeout"},{"line_number":414,"context_line":"            if self.conn:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_dc936e5a","line":411,"updated":"2018-05-11 18:32:34.000000000","message":"The yielded value is never used (the \u0027with\u0027 do not have \u0027as\u0027 parts). Not that it hurts anything...","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71e233b3759b3f4ef6374145764883e49a2c618d","unresolved":false,"context_lines":[{"line_number":408,"context_line":"            self.timeout \u003d new_timeout"},{"line_number":409,"context_line":"            if self.conn:"},{"line_number":410,"context_line":"                self.conn.timeout \u003d new_timeout"},{"line_number":411,"context_line":"            yield old_timeout"},{"line_number":412,"context_line":"        finally:"},{"line_number":413,"context_line":"            self.timeout \u003d old_timeout"},{"line_number":414,"context_line":"            if self.conn:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_a50bcfd3","line":411,"in_reply_to":"5f7c97a3_b2a6cdaa","updated":"2018-05-14 11:30:07.000000000","message":"tracking here https://trello.com/c/qU7nzcHy","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d57fac29389a2cdae651fa42ba581775a7a6ac64","unresolved":false,"context_lines":[{"line_number":408,"context_line":"            self.timeout \u003d new_timeout"},{"line_number":409,"context_line":"            if self.conn:"},{"line_number":410,"context_line":"                self.conn.timeout \u003d new_timeout"},{"line_number":411,"context_line":"            yield old_timeout"},{"line_number":412,"context_line":"        finally:"},{"line_number":413,"context_line":"            self.timeout \u003d old_timeout"},{"line_number":414,"context_line":"            if self.conn:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_b2a6cdaa","line":411,"in_reply_to":"5f7c97a3_dc936e5a","updated":"2018-05-11 19:48:44.000000000","message":"*shrug*\n\nThis might just go away, in favor of instantiating a new broker with an appropriate timeout... see the discussion at https://review.openstack.org/#/c/565742/1/swift/common/db.py@414","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":564,"context_line":"            curs.row_factory \u003d dict_factory"},{"line_number":565,"context_line":"            return [r for r in curs]"},{"line_number":566,"context_line":""},{"line_number":567,"context_line":"    def get_other_replication_items(self):"},{"line_number":568,"context_line":"        \"\"\""},{"line_number":569,"context_line":"        Subclasses may override this method to return a list of items that"},{"line_number":570,"context_line":"        should be replicated in addition to the list of objects returned by"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_c7387cef","line":567,"updated":"2018-05-10 22:58:32.000000000","message":"Not used yet ;-)\n\nI think this belongs in https://review.openstack.org/#/c/565744/\n\n*shrug*","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":564,"context_line":"            curs.row_factory \u003d dict_factory"},{"line_number":565,"context_line":"            return [r for r in curs]"},{"line_number":566,"context_line":""},{"line_number":567,"context_line":"    def get_other_replication_items(self):"},{"line_number":568,"context_line":"        \"\"\""},{"line_number":569,"context_line":"        Subclasses may override this method to return a list of items that"},{"line_number":570,"context_line":"        should be replicated in addition to the list of objects returned by"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_75002dac","line":567,"in_reply_to":"5f7c97a3_c7387cef","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":646,"context_line":"            return curs.fetchone()"},{"line_number":647,"context_line":""},{"line_number":648,"context_line":"    def put_record(self, record):"},{"line_number":649,"context_line":"        if self._db_file \u003d\u003d \u0027:memory:\u0027:"},{"line_number":650,"context_line":"            self.merge_items([record])"},{"line_number":651,"context_line":"            return"},{"line_number":652,"context_line":"        if not self._db_exists():"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_270db0a0","line":649,"updated":"2018-05-10 22:58:32.000000000","message":"Should this be\n\n if self._skip_commit_puts():\n\nnow? I worry about us silently dropping records with skip_commits\u003dTrue...","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":646,"context_line":"            return curs.fetchone()"},{"line_number":647,"context_line":""},{"line_number":648,"context_line":"    def put_record(self, record):"},{"line_number":649,"context_line":"        if self._db_file \u003d\u003d \u0027:memory:\u0027:"},{"line_number":650,"context_line":"            self.merge_items([record])"},{"line_number":651,"context_line":"            return"},{"line_number":652,"context_line":"        if not self._db_exists():"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_e106bb1c","line":649,"in_reply_to":"5f7c97a3_270db0a0","updated":"2018-05-11 14:26:48.000000000","message":"I think I\u0027d rather reinstate the exception if put_record is called when skip_commits is True to prevent future us inadvertently merging items into a \u0027read-only\u0027 broker","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"113e08d0319b98274ef945218aa2e46d3380d852","unresolved":false,"context_lines":[{"line_number":646,"context_line":"            return curs.fetchone()"},{"line_number":647,"context_line":""},{"line_number":648,"context_line":"    def put_record(self, record):"},{"line_number":649,"context_line":"        if self._db_file \u003d\u003d \u0027:memory:\u0027:"},{"line_number":650,"context_line":"            self.merge_items([record])"},{"line_number":651,"context_line":"            return"},{"line_number":652,"context_line":"        if not self._db_exists():"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_7f61ecd2","line":649,"in_reply_to":"5f7c97a3_270db0a0","updated":"2018-05-11 18:32:34.000000000","message":"The only time skip_commits is used is from the CLI tool... I thought it was basically the time when things are seriously screwed up.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d57fac29389a2cdae651fa42ba581775a7a6ac64","unresolved":false,"context_lines":[{"line_number":646,"context_line":"            return curs.fetchone()"},{"line_number":647,"context_line":""},{"line_number":648,"context_line":"    def put_record(self, record):"},{"line_number":649,"context_line":"        if self._db_file \u003d\u003d \u0027:memory:\u0027:"},{"line_number":650,"context_line":"            self.merge_items([record])"},{"line_number":651,"context_line":"            return"},{"line_number":652,"context_line":"        if not self._db_exists():"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_de535538","line":649,"in_reply_to":"5f7c97a3_7f61ecd2","updated":"2018-05-11 19:48:44.000000000","message":"We also use it when getting the sub-broker for the giant db -- see https://review.openstack.org/#/c/565744/5/swift/container/backend.py@1910","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":658,"context_line":"            except OSError as err:"},{"line_number":659,"context_line":"                if err.errno !\u003d errno.ENOENT:"},{"line_number":660,"context_line":"                    raise"},{"line_number":661,"context_line":"            if pending_size \u003e PENDING_CAP:"},{"line_number":662,"context_line":"                self._commit_puts([record])"},{"line_number":663,"context_line":"            else:"},{"line_number":664,"context_line":"                with open(self.pending_file, \u0027a+b\u0027) as fp:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_07df540d","line":661,"updated":"2018-05-10 22:58:32.000000000","message":"Alternatively, maybe this should be\n\n if pending_size \u003e PENDING_CAP and not self._skip_commit_puts():\n\n?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":658,"context_line":"            except OSError as err:"},{"line_number":659,"context_line":"                if err.errno !\u003d errno.ENOENT:"},{"line_number":660,"context_line":"                    raise"},{"line_number":661,"context_line":"            if pending_size \u003e PENDING_CAP:"},{"line_number":662,"context_line":"                self._commit_puts([record])"},{"line_number":663,"context_line":"            else:"},{"line_number":664,"context_line":"                with open(self.pending_file, \u0027a+b\u0027) as fp:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_611aab6f","line":661,"in_reply_to":"5f7c97a3_07df540d","updated":"2018-05-11 14:26:48.000000000","message":"ditto","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5951a6e114afca5dc9c695c4ff94426f5d23d060","unresolved":false,"context_lines":[{"line_number":358,"context_line":"            self._delete_db(conn, timestamp)"},{"line_number":359,"context_line":"            conn.commit()"},{"line_number":360,"context_line":""},{"line_number":361,"context_line":"    def _db_exists(self):"},{"line_number":362,"context_line":"        return self.db_file \u003d\u003d \u0027:memory:\u0027 or os.path.exists(self.db_file)"},{"line_number":363,"context_line":""},{"line_number":364,"context_line":"    @property"},{"line_number":365,"context_line":"    def db_file(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_0b75cdf9","line":362,"range":{"start_line":361,"start_character":0,"end_line":362,"end_character":73},"updated":"2018-05-15 17:33:35.000000000","message":"This was in the first commit to feature/deep, but then we stopped overriding it in https://review.openstack.org/#/c/515150/2/swift/container/backend.py, so i think this can be reverted to master.","commit_id":"ef65cea10160fe8c57a3c7737c1c8c11bb931b5f"},{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"42b10bb76bb09d4c8eb8161dffebf8479c5944e8","unresolved":false,"context_lines":[{"line_number":80,"context_line":"    zero in our databases for backwards compatibility with less disciplined"},{"line_number":81,"context_line":"    producers."},{"line_number":82,"context_line":"    \"\"\""},{"line_number":83,"context_line":"    return count in ZERO_LIKE_VALUES"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"def _db_timeout(timeout, db_file, call):"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f7c97a3_6c1d480e","line":83,"updated":"2018-05-17 17:06:55.000000000","message":"Poor old Christopher Null: https://www.wired.com/2015/11/null/","commit_id":"9d742b85ad2e53c1782116e56284e95a07577f35"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"1723ff2cddafccfad4fc8b3f31eefdf35571d642","unresolved":false,"context_lines":[{"line_number":80,"context_line":"    zero in our databases for backwards compatibility with less disciplined"},{"line_number":81,"context_line":"    producers."},{"line_number":82,"context_line":"    \"\"\""},{"line_number":83,"context_line":"    return count in ZERO_LIKE_VALUES"},{"line_number":84,"context_line":""},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"def _db_timeout(timeout, db_file, call):"}],"source_content_type":"text/x-python","patch_set":7,"id":"5f7c97a3_0c75b4fa","line":83,"in_reply_to":"5f7c97a3_6c1d480e","updated":"2018-05-17 17:14:32.000000000","message":"Hey, at least we didn\u0027t include\n\n \u0027None\u0027\n\nor\n\n \"\u0027\u0027\"","commit_id":"9d742b85ad2e53c1782116e56284e95a07577f35"}],"swift/common/db_replicator.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":320,"context_line":"            response \u003d http.replicate(\u0027merge_items\u0027, items, local_id)"},{"line_number":321,"context_line":"        if not response or response.status \u003e\u003d 300 \\"},{"line_number":322,"context_line":"                or response.status \u003c 200:"},{"line_number":323,"context_line":"            if response:"},{"line_number":324,"context_line":"                self.logger.error(_(\u0027ERROR Bad response %(status)s \u0027"},{"line_number":325,"context_line":"                                    \u0027from %(host)s\u0027),"},{"line_number":326,"context_line":"                                  {\u0027status\u0027: response.status,"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_77572804","line":323,"range":{"start_line":323,"start_character":15,"end_line":323,"end_character":23},"updated":"2018-05-08 00:03:33.000000000","message":"Note to self -- understand when response might be falsey.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":320,"context_line":"            response \u003d http.replicate(\u0027merge_items\u0027, items, local_id)"},{"line_number":321,"context_line":"        if not response or response.status \u003e\u003d 300 \\"},{"line_number":322,"context_line":"                or response.status \u003c 200:"},{"line_number":323,"context_line":"            if response:"},{"line_number":324,"context_line":"                self.logger.error(_(\u0027ERROR Bad response %(status)s \u0027"},{"line_number":325,"context_line":"                                    \u0027from %(host)s\u0027),"},{"line_number":326,"context_line":"                                  {\u0027status\u0027: response.status,"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_cb28cc87","line":323,"range":{"start_line":323,"start_character":15,"end_line":323,"end_character":23},"in_reply_to":"5f7c97a3_77572804","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":321,"context_line":"        if not response or response.status \u003e\u003d 300 \\"},{"line_number":322,"context_line":"                or response.status \u003c 200:"},{"line_number":323,"context_line":"            if response:"},{"line_number":324,"context_line":"                self.logger.error(_(\u0027ERROR Bad response %(status)s \u0027"},{"line_number":325,"context_line":"                                    \u0027from %(host)s\u0027),"},{"line_number":326,"context_line":"                                  {\u0027status\u0027: response.status,"},{"line_number":327,"context_line":"                                   \u0027host\u0027: http.host})"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_373c50c7","line":324,"range":{"start_line":324,"start_character":34,"end_line":324,"end_character":36},"updated":"2018-05-08 00:03:33.000000000","message":"nit: https://bugs.launchpad.net/swift/+bug/1674543","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":321,"context_line":"        if not response or response.status \u003e\u003d 300 \\"},{"line_number":322,"context_line":"                or response.status \u003c 200:"},{"line_number":323,"context_line":"            if response:"},{"line_number":324,"context_line":"                self.logger.error(_(\u0027ERROR Bad response %(status)s \u0027"},{"line_number":325,"context_line":"                                    \u0027from %(host)s\u0027),"},{"line_number":326,"context_line":"                                  {\u0027status\u0027: response.status,"},{"line_number":327,"context_line":"                                   \u0027host\u0027: http.host})"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_90144550","line":324,"range":{"start_line":324,"start_character":34,"end_line":324,"end_character":36},"in_reply_to":"5f7c97a3_373c50c7","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":361,"context_line":"        self.logger.debug(\u0027%s usyncing chunks to %s, finished at %s\u0027,"},{"line_number":362,"context_line":"                          broker.db_file,"},{"line_number":363,"context_line":"                          \u0027%(ip)s:%(port)s/%(device)s\u0027 % http.node,"},{"line_number":364,"context_line":"                          point)"},{"line_number":365,"context_line":""},{"line_number":366,"context_line":"        if objects:"},{"line_number":367,"context_line":"            self.logger.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_b77620a4","line":364,"updated":"2018-05-08 00:03:33.000000000","message":"I wonder if it would be worth including timing information, too...","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":361,"context_line":"        self.logger.debug(\u0027%s usyncing chunks to %s, finished at %s\u0027,"},{"line_number":362,"context_line":"                          broker.db_file,"},{"line_number":363,"context_line":"                          \u0027%(ip)s:%(port)s/%(device)s\u0027 % http.node,"},{"line_number":364,"context_line":"                          point)"},{"line_number":365,"context_line":""},{"line_number":366,"context_line":"        if objects:"},{"line_number":367,"context_line":"            self.logger.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_8bf3b40a","line":364,"in_reply_to":"5f7c97a3_b77620a4","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":496,"context_line":""},{"line_number":497,"context_line":"    def _post_replicate_hook(self, broker, info, responses):"},{"line_number":498,"context_line":"        \"\"\""},{"line_number":499,"context_line":"        :param broker: the container that just replicated"},{"line_number":500,"context_line":"        :param info: pre-replication full info dict"},{"line_number":501,"context_line":"        :param responses: a list of bools indicating success from nodes"},{"line_number":502,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_309a116e","line":499,"range":{"start_line":499,"start_character":27,"end_line":499,"end_character":37},"updated":"2018-05-08 10:11:34.000000000","message":"off topic: this is not only for container but also account?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":496,"context_line":""},{"line_number":497,"context_line":"    def _post_replicate_hook(self, broker, info, responses):"},{"line_number":498,"context_line":"        \"\"\""},{"line_number":499,"context_line":"        :param broker: the container that just replicated"},{"line_number":500,"context_line":"        :param info: pre-replication full info dict"},{"line_number":501,"context_line":"        :param responses: a list of bools indicating success from nodes"},{"line_number":502,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_2ba5bf04","line":499,"range":{"start_line":499,"start_character":27,"end_line":499,"end_character":37},"in_reply_to":"5f7c97a3_309a116e","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":507,"context_line":"        Cleanup non primary database from disk if needed."},{"line_number":508,"context_line":""},{"line_number":509,"context_line":"        :param broker: the broker for the database we\u0027re replicating"},{"line_number":510,"context_line":"        :param shouldbehere: boolean, True when the database path is in the"},{"line_number":511,"context_line":"                             correct part on a primary node"},{"line_number":512,"context_line":"        :param responses: a list of boolean success values for each replication"},{"line_number":513,"context_line":"                          request to other nodes"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_57930ca4","line":510,"range":{"start_line":510,"start_character":15,"end_line":510,"end_character":27},"updated":"2018-05-08 00:03:33.000000000","message":"Huh? orig_info, yeah?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":507,"context_line":"        Cleanup non primary database from disk if needed."},{"line_number":508,"context_line":""},{"line_number":509,"context_line":"        :param broker: the broker for the database we\u0027re replicating"},{"line_number":510,"context_line":"        :param shouldbehere: boolean, True when the database path is in the"},{"line_number":511,"context_line":"                             correct part on a primary node"},{"line_number":512,"context_line":"        :param responses: a list of boolean success values for each replication"},{"line_number":513,"context_line":"                          request to other nodes"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_b53e13d8","line":510,"range":{"start_line":510,"start_character":15,"end_line":510,"end_character":27},"in_reply_to":"5f7c97a3_57930ca4","updated":"2018-05-08 10:11:34.000000000","message":"it doesn\u0027t look just a naming issue because orig_info should be a dict including some keys (e.g. \u0027max_row\u0027) so it\u0027s not a boolean.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":507,"context_line":"        Cleanup non primary database from disk if needed."},{"line_number":508,"context_line":""},{"line_number":509,"context_line":"        :param broker: the broker for the database we\u0027re replicating"},{"line_number":510,"context_line":"        :param shouldbehere: boolean, True when the database path is in the"},{"line_number":511,"context_line":"                             correct part on a primary node"},{"line_number":512,"context_line":"        :param responses: a list of boolean success values for each replication"},{"line_number":513,"context_line":"                          request to other nodes"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_2b7e1f6b","line":510,"range":{"start_line":510,"start_character":15,"end_line":510,"end_character":27},"in_reply_to":"5f7c97a3_b53e13d8","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":514,"context_line":""},{"line_number":515,"context_line":"        :return success: boolean, False indicates cleanup was not successful"},{"line_number":516,"context_line":"        \"\"\""},{"line_number":517,"context_line":"        debug_template \u003d \u0027Not deleting db %s (%%s)\u0027 % broker.db_file"},{"line_number":518,"context_line":"        max_row_delta \u003d broker.get_max_row() - orig_info[\u0027max_row\u0027]"},{"line_number":519,"context_line":"        if max_row_delta:"},{"line_number":520,"context_line":"            reason \u003d \u0027%s new rows\u0027 % max_row_delta"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_d7871c61","line":517,"updated":"2018-05-08 00:03:33.000000000","message":"Well it\u0027s a good thing we\u0027re not trying to translate log messages any more... this sort of construction would make it difficult/impossible to do well.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":516,"context_line":"        \"\"\""},{"line_number":517,"context_line":"        debug_template \u003d \u0027Not deleting db %s (%%s)\u0027 % broker.db_file"},{"line_number":518,"context_line":"        max_row_delta \u003d broker.get_max_row() - orig_info[\u0027max_row\u0027]"},{"line_number":519,"context_line":"        if max_row_delta:"},{"line_number":520,"context_line":"            reason \u003d \u0027%s new rows\u0027 % max_row_delta"},{"line_number":521,"context_line":"            self.logger.debug(debug_template, reason)"},{"line_number":522,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_77f3a80b","line":519,"range":{"start_line":519,"start_character":11,"end_line":519,"end_character":24},"updated":"2018-05-08 00:03:33.000000000","message":"...and we\u0027re sure this can never go negative... right?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":516,"context_line":"        \"\"\""},{"line_number":517,"context_line":"        debug_template \u003d \u0027Not deleting db %s (%%s)\u0027 % broker.db_file"},{"line_number":518,"context_line":"        max_row_delta \u003d broker.get_max_row() - orig_info[\u0027max_row\u0027]"},{"line_number":519,"context_line":"        if max_row_delta:"},{"line_number":520,"context_line":"            reason \u003d \u0027%s new rows\u0027 % max_row_delta"},{"line_number":521,"context_line":"            self.logger.debug(debug_template, reason)"},{"line_number":522,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_c2bba16f","line":519,"range":{"start_line":519,"start_character":11,"end_line":519,"end_character":24},"in_reply_to":"5f7c97a3_14600932","updated":"2018-05-10 07:50:41.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":516,"context_line":"        \"\"\""},{"line_number":517,"context_line":"        debug_template \u003d \u0027Not deleting db %s (%%s)\u0027 % broker.db_file"},{"line_number":518,"context_line":"        max_row_delta \u003d broker.get_max_row() - orig_info[\u0027max_row\u0027]"},{"line_number":519,"context_line":"        if max_row_delta:"},{"line_number":520,"context_line":"            reason \u003d \u0027%s new rows\u0027 % max_row_delta"},{"line_number":521,"context_line":"            self.logger.debug(debug_template, reason)"},{"line_number":522,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_f02ed9f8","line":519,"range":{"start_line":519,"start_character":11,"end_line":519,"end_character":24},"in_reply_to":"5f7c97a3_77f3a80b","updated":"2018-05-08 10:11:34.000000000","message":"Looking at the code as micro, get_max_row() can return -1 for now so orig_info \u003d\u003d 0 and get_max_row() \u003d\u003d -1 would happen. IDK that situation can be occurred in the real running swift cluster tho.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":516,"context_line":"        \"\"\""},{"line_number":517,"context_line":"        debug_template \u003d \u0027Not deleting db %s (%%s)\u0027 % broker.db_file"},{"line_number":518,"context_line":"        max_row_delta \u003d broker.get_max_row() - orig_info[\u0027max_row\u0027]"},{"line_number":519,"context_line":"        if max_row_delta:"},{"line_number":520,"context_line":"            reason \u003d \u0027%s new rows\u0027 % max_row_delta"},{"line_number":521,"context_line":"            self.logger.debug(debug_template, reason)"},{"line_number":522,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_8b3173a5","line":519,"range":{"start_line":519,"start_character":11,"end_line":519,"end_character":24},"in_reply_to":"5f7c97a3_77f3a80b","updated":"2018-05-08 12:44:19.000000000","message":"you mean can the max rowid decrease? I don\u0027t think it can but if it did should we delete the db?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":516,"context_line":"        \"\"\""},{"line_number":517,"context_line":"        debug_template \u003d \u0027Not deleting db %s (%%s)\u0027 % broker.db_file"},{"line_number":518,"context_line":"        max_row_delta \u003d broker.get_max_row() - orig_info[\u0027max_row\u0027]"},{"line_number":519,"context_line":"        if max_row_delta:"},{"line_number":520,"context_line":"            reason \u003d \u0027%s new rows\u0027 % max_row_delta"},{"line_number":521,"context_line":"            self.logger.debug(debug_template, reason)"},{"line_number":522,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_d5b29894","line":519,"range":{"start_line":519,"start_character":11,"end_line":519,"end_character":24},"in_reply_to":"5f7c97a3_8b3173a5","updated":"2018-05-09 11:33:49.000000000","message":"I don\u0027t mean \"decrease\". Just looking at the code [1]. the code say, it can return -1 if no row found for the sequence. Probably it\u0027s an error case that we may ought to handle?\n\n1: https://github.com/openstack/swift/blob/master/swift/common/db.py#L560","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":516,"context_line":"        \"\"\""},{"line_number":517,"context_line":"        debug_template \u003d \u0027Not deleting db %s (%%s)\u0027 % broker.db_file"},{"line_number":518,"context_line":"        max_row_delta \u003d broker.get_max_row() - orig_info[\u0027max_row\u0027]"},{"line_number":519,"context_line":"        if max_row_delta:"},{"line_number":520,"context_line":"            reason \u003d \u0027%s new rows\u0027 % max_row_delta"},{"line_number":521,"context_line":"            self.logger.debug(debug_template, reason)"},{"line_number":522,"context_line":"            return True"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_14600932","line":519,"range":{"start_line":519,"start_character":11,"end_line":519,"end_character":24},"in_reply_to":"5f7c97a3_d5b29894","updated":"2018-05-09 14:39:21.000000000","message":"OK, I added an error log but I still think the best we can do is leave the db in place.\n\nI think there must be other places in Swift where there is an assumption that a call to get_max_row() always returns a value \u003e\u003d the last call to get_max_row().","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":524,"context_line":"            reason \u003d \u0027%s/%s success\u0027 % (responses.count(True), len(responses))"},{"line_number":525,"context_line":"            self.logger.debug(debug_template, reason)"},{"line_number":526,"context_line":"            return True"},{"line_number":527,"context_line":"        # If the db should not be on this node and has been successfully synced"},{"line_number":528,"context_line":"        # to all of its peers, it can be removed."},{"line_number":529,"context_line":"        if not self.delete_db(broker):"},{"line_number":530,"context_line":"            self.logger.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_17e27430","line":527,"range":{"start_line":527,"start_character":10,"end_line":527,"end_character":46},"updated":"2018-05-08 00:03:33.000000000","message":"Where was this check?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":524,"context_line":"            reason \u003d \u0027%s/%s success\u0027 % (responses.count(True), len(responses))"},{"line_number":525,"context_line":"            self.logger.debug(debug_template, reason)"},{"line_number":526,"context_line":"            return True"},{"line_number":527,"context_line":"        # If the db should not be on this node and has been successfully synced"},{"line_number":528,"context_line":"        # to all of its peers, it can be removed."},{"line_number":529,"context_line":"        if not self.delete_db(broker):"},{"line_number":530,"context_line":"            self.logger.debug("}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_8bd65327","line":527,"range":{"start_line":527,"start_character":10,"end_line":527,"end_character":46},"in_reply_to":"5f7c97a3_17e27430","updated":"2018-05-08 12:44:19.000000000","message":"the method previously included a check on shouldbehere as hinted by the stale docstring.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":526,"context_line":"            return True"},{"line_number":527,"context_line":"        # If the db should not be on this node and has been successfully synced"},{"line_number":528,"context_line":"        # to all of its peers, it can be removed."},{"line_number":529,"context_line":"        if not self.delete_db(broker):"},{"line_number":530,"context_line":"            self.logger.debug("},{"line_number":531,"context_line":"                \u0027Failed to delete db %s\u0027, broker.db_file)"},{"line_number":532,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_d0639d19","line":529,"updated":"2018-05-08 10:11:34.000000000","message":"Should we lock the dir where the db exist? Otherwise, a race condition can occur since the last check at the Line 519. Ah gah, the delete_db attempts to get the lock, too :/\n\nHmm... and more, it looks like no lock for merge_items and I\u0027m realizing this might be existing issue at the Swift master.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":526,"context_line":"            return True"},{"line_number":527,"context_line":"        # If the db should not be on this node and has been successfully synced"},{"line_number":528,"context_line":"        # to all of its peers, it can be removed."},{"line_number":529,"context_line":"        if not self.delete_db(broker):"},{"line_number":530,"context_line":"            self.logger.debug("},{"line_number":531,"context_line":"                \u0027Failed to delete db %s\u0027, broker.db_file)"},{"line_number":532,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_ebcfc77c","line":529,"in_reply_to":"5f7c97a3_d0639d19","updated":"2018-05-08 12:44:19.000000000","message":"For context see the original patch [1] - we have reduced but not eliminated the possibility of rows merging concurrently with the db being unlinked.\n\n[1] https://review.openstack.org/#/c/561091/","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":526,"context_line":"            return True"},{"line_number":527,"context_line":"        # If the db should not be on this node and has been successfully synced"},{"line_number":528,"context_line":"        # to all of its peers, it can be removed."},{"line_number":529,"context_line":"        if not self.delete_db(broker):"},{"line_number":530,"context_line":"            self.logger.debug("},{"line_number":531,"context_line":"                \u0027Failed to delete db %s\u0027, broker.db_file)"},{"line_number":532,"context_line":"            return False"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_f06562e2","line":529,"in_reply_to":"5f7c97a3_ebcfc77c","updated":"2018-05-09 11:33:49.000000000","message":"OK. It is NOT designed to eliminate the race but to mitigate the conflict. Possibly it doesn\u0027t happen so frequently because the commit should be  pend until the pending file filled up and the post_cleanup_failure occur only in the handoff node.\n\nIf it would trigger significant issue, let\u0027s do it at the time to consider better fixes.\n\nDone.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":545,"context_line":"            is True if the method completed successfully, False otherwise."},{"line_number":546,"context_line":"            ``responses`` is a list of booleans each of which indicates the"},{"line_number":547,"context_line":"            success or not of replicating to a peer node if replication has"},{"line_number":548,"context_line":"            been attempted. ``responses`` may be empty; ``success`` is False"},{"line_number":549,"context_line":"            if any of ``responses`` is False."},{"line_number":550,"context_line":"        \"\"\""},{"line_number":551,"context_line":"        start_time \u003d now \u003d time.time()"},{"line_number":552,"context_line":"        self.logger.debug(\u0027Replicating db %s\u0027, object_file)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_d7639cb0","line":549,"range":{"start_line":548,"start_character":28,"end_line":549,"end_character":44},"updated":"2018-05-08 00:03:33.000000000","message":"Maybe better as\n\n\u003e ``success`` is False if any of ``responses`` is False; when ``responses`` is empty, it may be either True or False.\n\nOtherwise, it sounds superfluous; why couldn\u0027t the caller just say\n\n success \u003d all(responses)","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":545,"context_line":"            is True if the method completed successfully, False otherwise."},{"line_number":546,"context_line":"            ``responses`` is a list of booleans each of which indicates the"},{"line_number":547,"context_line":"            success or not of replicating to a peer node if replication has"},{"line_number":548,"context_line":"            been attempted. ``responses`` may be empty; ``success`` is False"},{"line_number":549,"context_line":"            if any of ``responses`` is False."},{"line_number":550,"context_line":"        \"\"\""},{"line_number":551,"context_line":"        start_time \u003d now \u003d time.time()"},{"line_number":552,"context_line":"        self.logger.debug(\u0027Replicating db %s\u0027, object_file)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_cbc44b62","line":549,"range":{"start_line":548,"start_character":28,"end_line":549,"end_character":44},"in_reply_to":"5f7c97a3_d7639cb0","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":648,"context_line":"                                  \u0027hook for %s\u0027, broker.db_file)"},{"line_number":649,"context_line":"        if not shouldbehere:"},{"line_number":650,"context_line":"            success \u003d self.cleanup_post_replicate(broker, info, responses)"},{"line_number":651,"context_line":"            if not success:"},{"line_number":652,"context_line":"                failure_devs_info.update("},{"line_number":653,"context_line":"                    [(failure_dev[\u0027replication_ip\u0027], failure_dev[\u0027device\u0027])"},{"line_number":654,"context_line":"                     for failure_dev in repl_nodes])"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_576f8c91","line":651,"range":{"start_line":651,"start_character":19,"end_line":651,"end_character":26},"updated":"2018-05-08 00:03:33.000000000","message":"Do we ever use success after this? Should we just say\n\n if not self.cleanup_post_replicate(broker, info, responses):\n\nso we don\u0027t get confused with the notion of `success` defined up in the docstring?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":648,"context_line":"                                  \u0027hook for %s\u0027, broker.db_file)"},{"line_number":649,"context_line":"        if not shouldbehere:"},{"line_number":650,"context_line":"            success \u003d self.cleanup_post_replicate(broker, info, responses)"},{"line_number":651,"context_line":"            if not success:"},{"line_number":652,"context_line":"                failure_devs_info.update("},{"line_number":653,"context_line":"                    [(failure_dev[\u0027replication_ip\u0027], failure_dev[\u0027device\u0027])"},{"line_number":654,"context_line":"                     for failure_dev in repl_nodes])"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_f009f994","line":651,"range":{"start_line":651,"start_character":19,"end_line":651,"end_character":26},"in_reply_to":"5f7c97a3_576f8c91","updated":"2018-05-08 10:11:34.000000000","message":"+1 for docs. It looks like, FOR NOW, we assume it as success that no db deleted in the cleanup either when new rows found or when not all responses are successful...","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":648,"context_line":"                                  \u0027hook for %s\u0027, broker.db_file)"},{"line_number":649,"context_line":"        if not shouldbehere:"},{"line_number":650,"context_line":"            success \u003d self.cleanup_post_replicate(broker, info, responses)"},{"line_number":651,"context_line":"            if not success:"},{"line_number":652,"context_line":"                failure_devs_info.update("},{"line_number":653,"context_line":"                    [(failure_dev[\u0027replication_ip\u0027], failure_dev[\u0027device\u0027])"},{"line_number":654,"context_line":"                     for failure_dev in repl_nodes])"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_cb99ab79","line":651,"range":{"start_line":651,"start_character":19,"end_line":651,"end_character":26},"in_reply_to":"5f7c97a3_576f8c91","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":660,"context_line":""},{"line_number":661,"context_line":"        self.logger.timing_since(\u0027timing\u0027, start_time)"},{"line_number":662,"context_line":"        if shouldbehere:"},{"line_number":663,"context_line":"            responses.append(True)"},{"line_number":664,"context_line":"        return all(responses), responses"},{"line_number":665,"context_line":""},{"line_number":666,"context_line":"    def delete_db(self, broker):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_f01d7973","line":663,"updated":"2018-05-08 10:11:34.000000000","message":"Perhaps, this is for sure, all(responses) to be True even when 1 replica situation?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":660,"context_line":""},{"line_number":661,"context_line":"        self.logger.timing_since(\u0027timing\u0027, start_time)"},{"line_number":662,"context_line":"        if shouldbehere:"},{"line_number":663,"context_line":"            responses.append(True)"},{"line_number":664,"context_line":"        return all(responses), responses"},{"line_number":665,"context_line":""},{"line_number":666,"context_line":"    def delete_db(self, broker):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_50853659","line":663,"in_reply_to":"5f7c97a3_0b79e32d","updated":"2018-05-09 11:33:49.000000000","message":"Make sense. Done.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":660,"context_line":""},{"line_number":661,"context_line":"        self.logger.timing_since(\u0027timing\u0027, start_time)"},{"line_number":662,"context_line":"        if shouldbehere:"},{"line_number":663,"context_line":"            responses.append(True)"},{"line_number":664,"context_line":"        return all(responses), responses"},{"line_number":665,"context_line":""},{"line_number":666,"context_line":"    def delete_db(self, broker):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_0b79e32d","line":663,"in_reply_to":"5f7c97a3_f01d7973","updated":"2018-05-08 12:44:19.000000000","message":"yes, and to ensure that if responses is tested for a quorum to be True then the local primary is counted.\n\nSee ahead : https://review.openstack.org/#/c/565748/2/swift/container/sharder.py@1157","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":940,"context_line":"                    os.path.exists(old_filename))"},{"line_number":941,"context_line":""},{"line_number":942,"context_line":"    def rsync_then_merge(self, drive, db_file, args):"},{"line_number":943,"context_line":"        old_filename \u003d os.path.join(self.root, drive, \u0027tmp\u0027, args[0])"},{"line_number":944,"context_line":"        if self._abort_rsync_then_merge(db_file, old_filename):"},{"line_number":945,"context_line":"            return HTTPNotFound()"},{"line_number":946,"context_line":"        new_broker \u003d self.broker_class(old_filename)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_571d4c0d","line":943,"updated":"2018-05-08 00:03:33.000000000","message":"Off-topic: so if we abort, what eventually cleans up the tmp db?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":940,"context_line":"                    os.path.exists(old_filename))"},{"line_number":941,"context_line":""},{"line_number":942,"context_line":"    def rsync_then_merge(self, drive, db_file, args):"},{"line_number":943,"context_line":"        old_filename \u003d os.path.join(self.root, drive, \u0027tmp\u0027, args[0])"},{"line_number":944,"context_line":"        if self._abort_rsync_then_merge(db_file, old_filename):"},{"line_number":945,"context_line":"            return HTTPNotFound()"},{"line_number":946,"context_line":"        new_broker \u003d self.broker_class(old_filename)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_0bcc835f","line":943,"in_reply_to":"5f7c97a3_571d4c0d","updated":"2018-05-08 12:44:19.000000000","message":"maybe https://github.com/openstack/swift/blob/f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af/swift/common/db_replicator.py#L758","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":945,"context_line":"            return HTTPNotFound()"},{"line_number":946,"context_line":"        new_broker \u003d self.broker_class(old_filename)"},{"line_number":947,"context_line":"        existing_broker \u003d self.broker_class(db_file)"},{"line_number":948,"context_line":"        db_file \u003d existing_broker.db_file"},{"line_number":949,"context_line":"        point \u003d -1"},{"line_number":950,"context_line":"        objects \u003d existing_broker.get_items_since(point, 1000)"},{"line_number":951,"context_line":"        while len(objects):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_37221054","line":948,"updated":"2018-05-08 00:03:33.000000000","message":"Remind me -- why is this necessary? When would this *change* db_file?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":945,"context_line":"            return HTTPNotFound()"},{"line_number":946,"context_line":"        new_broker \u003d self.broker_class(old_filename)"},{"line_number":947,"context_line":"        existing_broker \u003d self.broker_class(db_file)"},{"line_number":948,"context_line":"        db_file \u003d existing_broker.db_file"},{"line_number":949,"context_line":"        point \u003d -1"},{"line_number":950,"context_line":"        objects \u003d existing_broker.get_items_since(point, 1000)"},{"line_number":951,"context_line":"        while len(objects):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_0b9ec353","line":948,"in_reply_to":"5f7c97a3_37221054","updated":"2018-05-08 12:44:19.000000000","message":"If existing_broker is for an epoch file.  This is catching corner cases. Ideally we would never rsync to a sharded db but the rsync may have started before sharding, or be to a collapsed db.\n\nhttps://review.openstack.org/#/c/563187/","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":318,"context_line":"    def _send_merge_items(self, http, local_id, items):"},{"line_number":319,"context_line":"        with Timeout(self.node_timeout):"},{"line_number":320,"context_line":"            response \u003d http.replicate(\u0027merge_items\u0027, items, local_id)"},{"line_number":321,"context_line":"        if not response or response.status \u003e\u003d 300 \\"},{"line_number":322,"context_line":"                or response.status \u003c 200:"},{"line_number":323,"context_line":"            if response:"},{"line_number":324,"context_line":"                self.logger.error(\u0027ERROR Bad response %s from %s\u0027,"},{"line_number":325,"context_line":"                                  response.status, http.host)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_f316a255","line":322,"range":{"start_line":321,"start_character":27,"end_line":322,"end_character":40},"updated":"2018-05-10 22:58:32.000000000","message":"Not you, but...\n\n not is_success(response.status)","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":318,"context_line":"    def _send_merge_items(self, http, local_id, items):"},{"line_number":319,"context_line":"        with Timeout(self.node_timeout):"},{"line_number":320,"context_line":"            response \u003d http.replicate(\u0027merge_items\u0027, items, local_id)"},{"line_number":321,"context_line":"        if not response or response.status \u003e\u003d 300 \\"},{"line_number":322,"context_line":"                or response.status \u003c 200:"},{"line_number":323,"context_line":"            if response:"},{"line_number":324,"context_line":"                self.logger.error(\u0027ERROR Bad response %s from %s\u0027,"},{"line_number":325,"context_line":"                                  response.status, http.host)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_e11f9b58","line":322,"range":{"start_line":321,"start_character":27,"end_line":322,"end_character":40},"in_reply_to":"5f7c97a3_f316a255","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":590,"context_line":"                                     for failure_dev in nodes])"},{"line_number":591,"context_line":"            self.logger.increment(\u0027failures\u0027)"},{"line_number":592,"context_line":"            return False, responses"},{"line_number":593,"context_line":"        if broker.is_reclaimable(now, self.reclaim_age):"},{"line_number":594,"context_line":"            if self.report_up_to_date(info):"},{"line_number":595,"context_line":"                self.delete_db(broker)"},{"line_number":596,"context_line":"            self.logger.timing_since(\u0027timing\u0027, start_time)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_53051613","line":593,"updated":"2018-05-10 22:58:32.000000000","message":"This incurs an extra DB hit now :-/","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":656,"context_line":"            if not self.cleanup_post_replicate(broker, info, responses):"},{"line_number":657,"context_line":"                failure_devs_info.update("},{"line_number":658,"context_line":"                    [(failure_dev[\u0027replication_ip\u0027], failure_dev[\u0027device\u0027])"},{"line_number":659,"context_line":"                     for failure_dev in repl_nodes])"},{"line_number":660,"context_line":"        target_devs_info \u003d set([(target_dev[\u0027replication_ip\u0027],"},{"line_number":661,"context_line":"                                 target_dev[\u0027device\u0027])"},{"line_number":662,"context_line":"                                for target_dev in repl_nodes])"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_3606481f","line":659,"updated":"2018-05-10 22:58:32.000000000","message":"Off-topic: this seems strange to me. We hit a *local* failure trying to delete our handoff db... so we mark all of the *remotes* as having failed?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":656,"context_line":"            if not self.cleanup_post_replicate(broker, info, responses):"},{"line_number":657,"context_line":"                failure_devs_info.update("},{"line_number":658,"context_line":"                    [(failure_dev[\u0027replication_ip\u0027], failure_dev[\u0027device\u0027])"},{"line_number":659,"context_line":"                     for failure_dev in repl_nodes])"},{"line_number":660,"context_line":"        target_devs_info \u003d set([(target_dev[\u0027replication_ip\u0027],"},{"line_number":661,"context_line":"                                 target_dev[\u0027device\u0027])"},{"line_number":662,"context_line":"                                for target_dev in repl_nodes])"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_214fd36b","line":659,"in_reply_to":"5f7c97a3_3606481f","updated":"2018-05-11 14:26:48.000000000","message":"agree","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":940,"context_line":"        renamer(old_filename, db_file)"},{"line_number":941,"context_line":"        return HTTPNoContent()"},{"line_number":942,"context_line":""},{"line_number":943,"context_line":"    def _abort_rsync_then_merge(self, db_file, old_filename):"},{"line_number":944,"context_line":"        return not (self._db_file_exists(db_file) and"},{"line_number":945,"context_line":"                    os.path.exists(old_filename))"},{"line_number":946,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_d606f41c","line":943,"range":{"start_line":943,"start_character":47,"end_line":943,"end_character":59},"updated":"2018-05-10 22:58:32.000000000","message":"Maybe better as tmp_filename, to make it clear that we\u0027re not in the normal tree (and therefore shouldn\u0027t use _db_file_exists)?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":940,"context_line":"        renamer(old_filename, db_file)"},{"line_number":941,"context_line":"        return HTTPNoContent()"},{"line_number":942,"context_line":""},{"line_number":943,"context_line":"    def _abort_rsync_then_merge(self, db_file, old_filename):"},{"line_number":944,"context_line":"        return not (self._db_file_exists(db_file) and"},{"line_number":945,"context_line":"                    os.path.exists(old_filename))"},{"line_number":946,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_61486b5b","line":943,"range":{"start_line":943,"start_character":47,"end_line":943,"end_character":59},"in_reply_to":"5f7c97a3_d606f41c","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"113e08d0319b98274ef945218aa2e46d3380d852","unresolved":false,"context_lines":[{"line_number":950,"context_line":"            return HTTPNotFound()"},{"line_number":951,"context_line":"        new_broker \u003d self.broker_class(old_filename)"},{"line_number":952,"context_line":"        existing_broker \u003d self.broker_class(db_file)"},{"line_number":953,"context_line":"        db_file \u003d existing_broker.db_file"},{"line_number":954,"context_line":"        point \u003d -1"},{"line_number":955,"context_line":"        objects \u003d existing_broker.get_items_since(point, 1000)"},{"line_number":956,"context_line":"        while len(objects):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_de711546","line":953,"updated":"2018-05-11 18:32:34.000000000","message":"Woa woa woa! How does this happen - you make a broker and that makes the DB file to rename... to a different timestamp or something? My imagination cannot reach far enough, sorry.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d57fac29389a2cdae651fa42ba581775a7a6ac64","unresolved":false,"context_lines":[{"line_number":950,"context_line":"            return HTTPNotFound()"},{"line_number":951,"context_line":"        new_broker \u003d self.broker_class(old_filename)"},{"line_number":952,"context_line":"        existing_broker \u003d self.broker_class(db_file)"},{"line_number":953,"context_line":"        db_file \u003d existing_broker.db_file"},{"line_number":954,"context_line":"        point \u003d -1"},{"line_number":955,"context_line":"        objects \u003d existing_broker.get_items_since(point, 1000)"},{"line_number":956,"context_line":"        while len(objects):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_f210c550","line":953,"in_reply_to":"5f7c97a3_de711546","updated":"2018-05-11 19:48:44.000000000","message":"Quoting Alistair at https://review.openstack.org/#/c/565742/1/swift/common/db_replicator.py@948 :\n\n\u003e [db_file might change i]f existing_broker is for an epoch file. This is catching corner cases. Ideally we would never rsync to a sharded db but the rsync may have started before sharding, or be to a collapsed db.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"71e233b3759b3f4ef6374145764883e49a2c618d","unresolved":false,"context_lines":[{"line_number":950,"context_line":"            return HTTPNotFound()"},{"line_number":951,"context_line":"        new_broker \u003d self.broker_class(old_filename)"},{"line_number":952,"context_line":"        existing_broker \u003d self.broker_class(db_file)"},{"line_number":953,"context_line":"        db_file \u003d existing_broker.db_file"},{"line_number":954,"context_line":"        point \u003d -1"},{"line_number":955,"context_line":"        objects \u003d existing_broker.get_items_since(point, 1000)"},{"line_number":956,"context_line":"        while len(objects):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_25b01f8a","line":953,"in_reply_to":"5f7c97a3_f210c550","updated":"2018-05-14 11:30:07.000000000","message":"Creating a ContainerBroker is now a little like creating a diskfile instance in that it is the path to the db\u0027s *directory* that matters, then the broker finds whatever files are there and does the right thing.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":958,"context_line":"            point \u003d objects[-1][\u0027ROWID\u0027]"},{"line_number":959,"context_line":"            objects \u003d existing_broker.get_items_since(point, 1000)"},{"line_number":960,"context_line":"            sleep()"},{"line_number":961,"context_line":"        new_broker.merge_syncs(existing_broker.get_syncs())"},{"line_number":962,"context_line":"        new_broker.newid(args[0])"},{"line_number":963,"context_line":"        new_broker.update_metadata(existing_broker.metadata)"},{"line_number":964,"context_line":"        if self._abort_rsync_then_merge(db_file, old_filename):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_561ae46e","line":961,"updated":"2018-05-10 22:58:32.000000000","message":"Do we expect much to be in the existing DB\u0027s sync tables? The idea is that the existing db is so far out of date that this is more expedient -- wouldn\u0027t any other primaries that talked to it come to the same conclusion?\n\nAssuming we keep this, should we merge outgoing sync points, too?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":958,"context_line":"            point \u003d objects[-1][\u0027ROWID\u0027]"},{"line_number":959,"context_line":"            objects \u003d existing_broker.get_items_since(point, 1000)"},{"line_number":960,"context_line":"            sleep()"},{"line_number":961,"context_line":"        new_broker.merge_syncs(existing_broker.get_syncs())"},{"line_number":962,"context_line":"        new_broker.newid(args[0])"},{"line_number":963,"context_line":"        new_broker.update_metadata(existing_broker.metadata)"},{"line_number":964,"context_line":"        if self._abort_rsync_then_merge(db_file, old_filename):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_a199a3c4","line":961,"in_reply_to":"5f7c97a3_561ae46e","updated":"2018-05-11 14:26:48.000000000","message":"Why would we not merge the incoming syncs? They are still valid, and it is more likely that, once this rsync_then_merge has completed, other replication sources are going to choose usync.\n\nAs for outgoing syncs...IDK, I\u0027d need to understand them better :/","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d57fac29389a2cdae651fa42ba581775a7a6ac64","unresolved":false,"context_lines":[{"line_number":958,"context_line":"            point \u003d objects[-1][\u0027ROWID\u0027]"},{"line_number":959,"context_line":"            objects \u003d existing_broker.get_items_since(point, 1000)"},{"line_number":960,"context_line":"            sleep()"},{"line_number":961,"context_line":"        new_broker.merge_syncs(existing_broker.get_syncs())"},{"line_number":962,"context_line":"        new_broker.newid(args[0])"},{"line_number":963,"context_line":"        new_broker.update_metadata(existing_broker.metadata)"},{"line_number":964,"context_line":"        if self._abort_rsync_then_merge(db_file, old_filename):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_52d3b960","line":961,"in_reply_to":"5f7c97a3_a199a3c4","updated":"2018-05-11 19:48:44.000000000","message":"If we\u0027re in rsync_then_merge, we must assume that existing_broker has far fewer rows than new_broker... which means that any sync points in existing_broker would be for databases that *also* have far fewer rows than new_broker. So *that* DB will eventually take an rsync_then_merge *itself* and get re-id\u0027ed... and we\u0027re going to have to usync everything over afterwards *anyway* :-(\n\nI\u0027m not actually opposed to doing this -- I\u0027m just frustrated at our own inefficiencies.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":959,"context_line":"            objects \u003d existing_broker.get_items_since(point, 1000)"},{"line_number":960,"context_line":"            sleep()"},{"line_number":961,"context_line":"        new_broker.merge_syncs(existing_broker.get_syncs())"},{"line_number":962,"context_line":"        new_broker.newid(args[0])"},{"line_number":963,"context_line":"        new_broker.update_metadata(existing_broker.metadata)"},{"line_number":964,"context_line":"        if self._abort_rsync_then_merge(db_file, old_filename):"},{"line_number":965,"context_line":"            return HTTPNotFound()"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_362f288f","line":962,"updated":"2018-05-10 22:58:32.000000000","message":"Off-topic: Ugh, db replication sucks! So following a rebalance,\n\n- an existing primary rsyncs (or rsync-then-merges) to the new primary,\n- new primary gets a new ID that no one else has heard of,\n- so it proceeds to need to usync all of its rows (100k at a time) to the other replicas!\n\nMeanwhile, the poor old primary that\u0027s now a handoff discovers the new DB and needs to usync all of its rows to the new guy before it can delete itself!","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":959,"context_line":"            objects \u003d existing_broker.get_items_since(point, 1000)"},{"line_number":960,"context_line":"            sleep()"},{"line_number":961,"context_line":"        new_broker.merge_syncs(existing_broker.get_syncs())"},{"line_number":962,"context_line":"        new_broker.newid(args[0])"},{"line_number":963,"context_line":"        new_broker.update_metadata(existing_broker.metadata)"},{"line_number":964,"context_line":"        if self._abort_rsync_then_merge(db_file, old_filename):"},{"line_number":965,"context_line":"            return HTTPNotFound()"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_015df7e7","line":962,"in_reply_to":"5f7c97a3_362f288f","updated":"2018-05-11 14:26:48.000000000","message":"yep!\n\nplus, I think:\n- existing primary rsyncs to new primary\n- either gains one row\n- now they will have to usync all rows to each other!\n\nI would at least like this method to return a header with the new id, and have the replication source add it to its incoming syncs (and outgoing syncs?), so that when the new primary replicates to existing it only usyncs from the row at time of rsync.\n\nMore generally, we need a way of recording that \u0027if you are in sync with id_x at row_x, then you are also in sync with id_y at row_y\u0027","commit_id":"1815146a149a51ec759399986846f1962363b0e8"}],"swift/common/wsgi.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":46,"context_line":"    reiterate"},{"line_number":47,"context_line":""},{"line_number":48,"context_line":"SIGNUM_TO_NAME \u003d {getattr(signal, n): n for n in dir(signal)"},{"line_number":49,"context_line":"                  if n.startswith(\u0027SIG\u0027) and \u0027_\u0027 not in n}"},{"line_number":50,"context_line":""},{"line_number":51,"context_line":"# Set maximum line size of message headers to be accepted."},{"line_number":52,"context_line":"wsgi.MAX_HEADER_LINE \u003d constraints.MAX_HEADER_SIZE"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_f71b3818","line":49,"updated":"2018-05-08 00:03:33.000000000","message":"I kinda wonder if this belongs in utils, but w/e","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":943,"context_line":"    def stop_with_signal(signum, *args):"},{"line_number":944,"context_line":"        \"\"\"Set running to False and capture the signum\"\"\""},{"line_number":945,"context_line":"        running[0] \u003d False"},{"line_number":946,"context_line":"        running[1] \u003d signum"},{"line_number":947,"context_line":""},{"line_number":948,"context_line":"    running \u003d [True, None]"},{"line_number":949,"context_line":"    signal.signal(signal.SIGTERM, stop_with_signal)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_77dde840","line":946,"range":{"start_line":946,"start_character":8,"end_line":946,"end_character":15},"updated":"2018-05-08 00:03:33.000000000","message":"nit: might be worth renaming now that this holds more than just the running state...","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":943,"context_line":"    def stop_with_signal(signum, *args):"},{"line_number":944,"context_line":"        \"\"\"Set running to False and capture the signum\"\"\""},{"line_number":945,"context_line":"        running[0] \u003d False"},{"line_number":946,"context_line":"        running[1] \u003d signum"},{"line_number":947,"context_line":""},{"line_number":948,"context_line":"    running \u003d [True, None]"},{"line_number":949,"context_line":"    signal.signal(signal.SIGTERM, stop_with_signal)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_6bbe5766","line":946,"range":{"start_line":946,"start_character":8,"end_line":946,"end_character":15},"in_reply_to":"5f7c97a3_77dde840","updated":"2018-05-08 12:44:19.000000000","message":"Done","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":987,"context_line":"                        # events that happen. The value of 0.01 matches the"},{"line_number":988,"context_line":"                        # value in eventlet\u0027s waitpid()."},{"line_number":989,"context_line":"                        sleep(0.01)"},{"line_number":990,"context_line":"            except KeyboardInterrupt:"},{"line_number":991,"context_line":"                logger.notice(\u0027User quit\u0027)"},{"line_number":992,"context_line":"                running[0] \u003d False"},{"line_number":993,"context_line":"                break"},{"line_number":994,"context_line":""},{"line_number":995,"context_line":"    if running[1] is not None:"},{"line_number":996,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_57f54c82","line":993,"range":{"start_line":990,"start_character":12,"end_line":993,"end_character":21},"updated":"2018-05-08 00:03:33.000000000","message":"Makes me wonder if we should just have stop_with_signal also handle SIGINT...","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":1002,"context_line":"    if running[1] \u003d\u003d signal.SIGTERM:"},{"line_number":1003,"context_line":"        os.killpg(0, signal.SIGTERM)"},{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"    strategy.shutdown_sockets()"},{"line_number":1006,"context_line":"    signal.signal(signal.SIGTERM, signal.SIG_IGN)"},{"line_number":1007,"context_line":"    logger.notice(\u0027Exited (%s)\u0027, os.getpid())"},{"line_number":1008,"context_line":"    return 0"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_b762a03d","line":1005,"updated":"2018-05-08 00:03:33.000000000","message":"Can this block at all? I just worry a little about getting a SIGHUP to attempt a graceful shutdown then getting stuck somewhere after we might call killpg -- so a subsequent SIGTERM wouldn\u0027t help.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":1003,"context_line":"        os.killpg(0, signal.SIGTERM)"},{"line_number":1004,"context_line":""},{"line_number":1005,"context_line":"    strategy.shutdown_sockets()"},{"line_number":1006,"context_line":"    signal.signal(signal.SIGTERM, signal.SIG_IGN)"},{"line_number":1007,"context_line":"    logger.notice(\u0027Exited (%s)\u0027, os.getpid())"},{"line_number":1008,"context_line":"    return 0"},{"line_number":1009,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_37d1b0fc","line":1006,"range":{"start_line":1006,"start_character":25,"end_line":1006,"end_character":32},"updated":"2018-05-08 00:03:33.000000000","message":"Why do we clear our SIGTERM handler but not SIGHUP?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":991,"context_line":"            except KeyboardInterrupt:"},{"line_number":992,"context_line":"                logger.notice(\u0027User quit\u0027)"},{"line_number":993,"context_line":"                running_context[0] \u003d False"},{"line_number":994,"context_line":"                break"},{"line_number":995,"context_line":""},{"line_number":996,"context_line":"    if running_context[1] is not None:"},{"line_number":997,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_960f1c36","line":994,"updated":"2018-05-10 22:58:32.000000000","message":"This still seems not-crazy to me:\n\n diff --git a/swift/common/wsgi.py b/swift/common/wsgi.py\n index 2a9409d92..5dada0bdd 100644\n --- a/swift/common/wsgi.py\n +++ b/swift/common/wsgi.py\n @@ -949,6 +949,7 @@ def run_wsgi(conf_path, app_section, *args, **kwargs):\n      running_context \u003d [True, None]\n      signal.signal(signal.SIGTERM, stop_with_signal)\n      signal.signal(signal.SIGHUP, stop_with_signal)\n +    signal.signal(signal.SIGINT, stop_with_signal)\n  \n      while running_context[0]:\n          for sock, sock_info in strategy.new_worker_socks():\n @@ -956,6 +957,7 @@ def run_wsgi(conf_path, app_section, *args, **kwargs):\n              if pid \u003d\u003d 0:\n                  signal.signal(signal.SIGHUP, signal.SIG_DFL)\n                  signal.signal(signal.SIGTERM, signal.SIG_DFL)\n +                signal.signal(signal.SIGINT, signal.SIG_DFL)\n                  strategy.post_fork_hook()\n                  run_server(conf, logger, sock)\n                  strategy.log_sock_exit(sock, sock_info)\n @@ -973,25 +975,20 @@ def run_wsgi(conf_path, app_section, *args, **kwargs):\n  \n          with Timeout(loop_timeout, exception\u003dFalse):\n              try:\n -                try:\n -                    pid, status \u003d green_os.wait()\n -                    if os.WIFEXITED(status) or os.WIFSIGNALED(status):\n -                        strategy.register_worker_exit(pid)\n -                except OSError as err:\n -                    if err.errno not in (errno.EINTR, errno.ECHILD):\n -                        raise\n -                    if err.errno \u003d\u003d errno.ECHILD:\n -                        # If there are no children at all (ECHILD), then\n -                        # there\u0027s nothing to actually wait on. We sleep\n -                        # for a little bit to avoid a tight CPU spin\n -                        # and still are able to catch any KeyboardInterrupt\n -                        # events that happen. The value of 0.01 matches the\n -                        # value in eventlet\u0027s waitpid().\n -                        sleep(0.01)\n -            except KeyboardInterrupt:\n -                logger.notice(\u0027User quit\u0027)\n -                running_context[0] \u003d False\n -                break\n +                pid, status \u003d green_os.wait()\n +                if os.WIFEXITED(status) or os.WIFSIGNALED(status):\n +                    strategy.register_worker_exit(pid)\n +            except OSError as err:\n +                if err.errno not in (errno.EINTR, errno.ECHILD):\n +                    raise\n +                if err.errno \u003d\u003d errno.ECHILD:\n +                    # If there are no children at all (ECHILD), then\n +                    # there\u0027s nothing to actually wait on. We sleep\n +                    # for a little bit to avoid a tight CPU spin\n +                    # and still are able to catch any KeyboardInterrupt\n +                    # events that happen. The value of 0.01 matches the\n +                    # value in eventlet\u0027s waitpid().\n +                    sleep(0.01)\n  \n      if running_context[1] is not None:\n          try:","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e8917b8e03fe4ee4dfb424e1b572a9c1b3e799f1","unresolved":false,"context_lines":[{"line_number":991,"context_line":"            except KeyboardInterrupt:"},{"line_number":992,"context_line":"                logger.notice(\u0027User quit\u0027)"},{"line_number":993,"context_line":"                running_context[0] \u003d False"},{"line_number":994,"context_line":"                break"},{"line_number":995,"context_line":""},{"line_number":996,"context_line":"    if running_context[1] is not None:"},{"line_number":997,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_35114705","line":994,"in_reply_to":"5f7c97a3_410c4fec","updated":"2018-05-11 20:26:45.000000000","message":"https://review.openstack.org/567939 -- depends on https://review.openstack.org/567938","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":991,"context_line":"            except KeyboardInterrupt:"},{"line_number":992,"context_line":"                logger.notice(\u0027User quit\u0027)"},{"line_number":993,"context_line":"                running_context[0] \u003d False"},{"line_number":994,"context_line":"                break"},{"line_number":995,"context_line":""},{"line_number":996,"context_line":"    if running_context[1] is not None:"},{"line_number":997,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_410c4fec","line":994,"in_reply_to":"5f7c97a3_960f1c36","updated":"2018-05-11 14:26:48.000000000","message":"how about putting this in a temporary follow on patch and let\u0027s get some discussion there, then squash if agreement is reached?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1002,"context_line":"        else:"},{"line_number":1003,"context_line":"            logger.error(\u0027%s received\u0027, signame)"},{"line_number":1004,"context_line":"    if running_context[1] \u003d\u003d signal.SIGTERM:"},{"line_number":1005,"context_line":"        os.killpg(0, signal.SIGTERM)"},{"line_number":1006,"context_line":""},{"line_number":1007,"context_line":"    strategy.shutdown_sockets()"},{"line_number":1008,"context_line":"    signal.signal(signal.SIGTERM, signal.SIG_IGN)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_36ce482e","line":1005,"updated":"2018-05-10 22:58:32.000000000","message":"I\u0027ve still got this nagging worry about how we don\u0027t do this in the signal handler anymore...","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1005,"context_line":"        os.killpg(0, signal.SIGTERM)"},{"line_number":1006,"context_line":""},{"line_number":1007,"context_line":"    strategy.shutdown_sockets()"},{"line_number":1008,"context_line":"    signal.signal(signal.SIGTERM, signal.SIG_IGN)"},{"line_number":1009,"context_line":"    logger.notice(\u0027Exited (%s)\u0027, os.getpid())"},{"line_number":1010,"context_line":"    return 0"},{"line_number":1011,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_96dcfce4","line":1008,"updated":"2018-05-10 22:58:32.000000000","message":"And it still weirds me out that we never do a\n\n signal.signal(signal.SIGHUP, signal.SIG_IGN)\n\nSomething like this might be better?\n\n diff --git a/swift/common/wsgi.py b/swift/common/wsgi.py\n index 2a9409d92..f0797fd8a 100644\n --- a/swift/common/wsgi.py\n +++ b/swift/common/wsgi.py\n @@ -944,6 +944,9 @@ def run_wsgi(conf_path, app_section, *args, **kwargs):\n          \"\"\"Set running flag to False and capture the signum\"\"\"\n          running_context[0] \u003d False\n          running_context[1] \u003d signum\n +        if signum \u003d\u003d signal.SIGTERM:\n +            os.killpg(0, signal.SIGTERM)\n +        signal.signal(signum, signal.SIG_IGN)\n  \n      # context to hold boolean running state and stop signum\n      running_context \u003d [True, None]\n @@ -1001,11 +1004,8 @@ def run_wsgi(conf_path, app_section, *args, **kwargs):\n                           running_context[1])\n          else:\n              logger.error(\u0027%s received\u0027, signame)\n -    if running_context[1] \u003d\u003d signal.SIGTERM:\n -        os.killpg(0, signal.SIGTERM)\n  \n      strategy.shutdown_sockets()\n -    signal.signal(signal.SIGTERM, signal.SIG_IGN)\n      logger.notice(\u0027Exited (%s)\u0027, os.getpid())\n      return 0","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e8917b8e03fe4ee4dfb424e1b572a9c1b3e799f1","unresolved":false,"context_lines":[{"line_number":1005,"context_line":"        os.killpg(0, signal.SIGTERM)"},{"line_number":1006,"context_line":""},{"line_number":1007,"context_line":"    strategy.shutdown_sockets()"},{"line_number":1008,"context_line":"    signal.signal(signal.SIGTERM, signal.SIG_IGN)"},{"line_number":1009,"context_line":"    logger.notice(\u0027Exited (%s)\u0027, os.getpid())"},{"line_number":1010,"context_line":"    return 0"},{"line_number":1011,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_150c4bea","line":1008,"in_reply_to":"5f7c97a3_0112d709","updated":"2018-05-11 20:26:45.000000000","message":"https://review.openstack.org/567938","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1005,"context_line":"        os.killpg(0, signal.SIGTERM)"},{"line_number":1006,"context_line":""},{"line_number":1007,"context_line":"    strategy.shutdown_sockets()"},{"line_number":1008,"context_line":"    signal.signal(signal.SIGTERM, signal.SIG_IGN)"},{"line_number":1009,"context_line":"    logger.notice(\u0027Exited (%s)\u0027, os.getpid())"},{"line_number":1010,"context_line":"    return 0"},{"line_number":1011,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_0112d709","line":1008,"in_reply_to":"5f7c97a3_96dcfce4","updated":"2018-05-11 14:26:48.000000000","message":"ditto re discuss in a temp patch review","commit_id":"1815146a149a51ec759399986846f1962363b0e8"}],"swift/container/backend.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":807,"context_line":"        Decode the created_at timestamp into separate data, content-type and"},{"line_number":808,"context_line":"        meta timestamps and replace the created_at timestamp with the"},{"line_number":809,"context_line":"        metadata timestamp i.e. the last-modified time. Also, drop"},{"line_number":810,"context_line":"        storage_policy_index from the record."},{"line_number":811,"context_line":"        \"\"\""},{"line_number":812,"context_line":"        t_data, t_ctype, t_meta \u003d decode_timestamps(record[1])"},{"line_number":813,"context_line":"        return (record[0], t_meta.internal) + record[2:6]"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_5751cc61","line":810,"updated":"2018-05-08 00:03:33.000000000","message":"...\n\nWhy?\n\nIf memory serves... something about wanting to allow more replicate args in the future? Have I got that right?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":807,"context_line":"        Decode the created_at timestamp into separate data, content-type and"},{"line_number":808,"context_line":"        meta timestamps and replace the created_at timestamp with the"},{"line_number":809,"context_line":"        metadata timestamp i.e. the last-modified time. Also, drop"},{"line_number":810,"context_line":"        storage_policy_index from the record."},{"line_number":811,"context_line":"        \"\"\""},{"line_number":812,"context_line":"        t_data, t_ctype, t_meta \u003d decode_timestamps(record[1])"},{"line_number":813,"context_line":"        return (record[0], t_meta.internal) + record[2:6]"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_6e60a5a6","line":810,"in_reply_to":"5f7c97a3_5751cc61","updated":"2018-05-08 12:44:19.000000000","message":"This change is in the wrong patch, I\u0027ll move it ... but later we change list_objects_iter to select more attributes for each object record, so to preserve the default interface  we need to then truncate the record. We should also be dropping \u0027deleted\u0027.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":476,"context_line":"        with self.get() as conn:"},{"line_number":477,"context_line":"            info \u003d conn.execute(\u0027\u0027\u0027"},{"line_number":478,"context_line":"                SELECT put_timestamp, delete_timestamp"},{"line_number":479,"context_line":"                FROM container_stat\u0027\u0027\u0027).fetchone()"},{"line_number":480,"context_line":"        if (Timestamp(now - reclaim_age) \u003e"},{"line_number":481,"context_line":"            Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":482,"context_line":"                Timestamp(info[\u0027put_timestamp\u0027])):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_f0900251","line":479,"updated":"2018-05-09 11:33:49.000000000","message":"Same comment with account/backend.\n\nself.get_info can work. Ah... the difference would be the existence of self._commit_puts_stale_ok()??? Is it intended?","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":476,"context_line":"        with self.get() as conn:"},{"line_number":477,"context_line":"            info \u003d conn.execute(\u0027\u0027\u0027"},{"line_number":478,"context_line":"                SELECT put_timestamp, delete_timestamp"},{"line_number":479,"context_line":"                FROM container_stat\u0027\u0027\u0027).fetchone()"},{"line_number":480,"context_line":"        if (Timestamp(now - reclaim_age) \u003e"},{"line_number":481,"context_line":"            Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":482,"context_line":"                Timestamp(info[\u0027put_timestamp\u0027])):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_3dd638f3","line":479,"in_reply_to":"5f7c97a3_14d569b9","updated":"2018-05-10 07:50:41.000000000","message":"Make sense. Thanks. Done.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":476,"context_line":"        with self.get() as conn:"},{"line_number":477,"context_line":"            info \u003d conn.execute(\u0027\u0027\u0027"},{"line_number":478,"context_line":"                SELECT put_timestamp, delete_timestamp"},{"line_number":479,"context_line":"                FROM container_stat\u0027\u0027\u0027).fetchone()"},{"line_number":480,"context_line":"        if (Timestamp(now - reclaim_age) \u003e"},{"line_number":481,"context_line":"            Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":482,"context_line":"                Timestamp(info[\u0027put_timestamp\u0027])):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_14d569b9","line":479,"in_reply_to":"5f7c97a3_f0900251","updated":"2018-05-09 14:39:21.000000000","message":"yes, it is intentional - the _commit_puts_stale_ok is called in the empty() method only is the timestamps suggest the db is deleted","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"}],"swift/container/replicator.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":86,"context_line":"        db_dir \u003d storage_directory(DATADIR, part, hsh)"},{"line_number":87,"context_line":"        db_path \u003d os.path.join(self.root, device, db_dir, hsh + \u0027.db\u0027)"},{"line_number":88,"context_line":"        broker \u003d ContainerBroker(db_path, account\u003daccount, container\u003dcontainer,"},{"line_number":89,"context_line":"                                 logger\u003dself.logger)"},{"line_number":90,"context_line":"        if not os.path.exists(broker.db_file):"},{"line_number":91,"context_line":"            try:"},{"line_number":92,"context_line":"                broker.initialize(**kwargs)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_f7fd783a","line":89,"range":{"start_line":89,"start_character":33,"end_line":89,"end_character":51},"updated":"2018-05-08 00:03:33.000000000","message":"+1, surely a good idea.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":131,"context_line":"                \u0027container %s in partition %s\u0027 % (container, part))"},{"line_number":132,"context_line":"        broker \u003d self._initialize_broker("},{"line_number":133,"context_line":"            node[\u0027device\u0027], part, account, container,"},{"line_number":134,"context_line":"            put_timestamp\u003dtimestamp, storage_policy_index\u003d0)"},{"line_number":135,"context_line":"        if self.reconciler_containers is not None:"},{"line_number":136,"context_line":"            self.reconciler_containers[container] \u003d part, broker, node[\u0027id\u0027]"},{"line_number":137,"context_line":"        return broker"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_779f2803","line":134,"range":{"start_line":134,"start_character":12,"end_line":134,"end_character":59},"updated":"2018-05-08 00:03:33.000000000","message":"+1, way more explicit than just\n\n timestamp, 0","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    default_port \u003d 6201"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def __init__(self, conf, logger\u003dNone):"},{"line_number":43,"context_line":"        super(ContainerReplicator, self).__init__(conf, logger\u003dlogger)"},{"line_number":44,"context_line":"        self.reconciler_cleanups \u003d self.sync_store \u003d None"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def report_up_to_date(self, full_info):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_50077683","line":43,"range":{"start_line":43,"start_character":8,"end_line":43,"end_character":70},"updated":"2018-05-09 11:33:49.000000000","message":"nits) super(ContainerReplicator, self).__init__(conf, logger)\n\nNo keyword required.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    default_port \u003d 6201"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def __init__(self, conf, logger\u003dNone):"},{"line_number":43,"context_line":"        super(ContainerReplicator, self).__init__(conf, logger\u003dlogger)"},{"line_number":44,"context_line":"        self.reconciler_cleanups \u003d self.sync_store \u003d None"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def report_up_to_date(self, full_info):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_d4fff131","line":43,"range":{"start_line":43,"start_character":8,"end_line":43,"end_character":70},"in_reply_to":"5f7c97a3_50077683","updated":"2018-05-09 14:39:21.000000000","message":"not required but I prefer to use named arg in case the superclass signature is changed, since it is a kwarg in the superclass.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":40,"context_line":"    default_port \u003d 6201"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def __init__(self, conf, logger\u003dNone):"},{"line_number":43,"context_line":"        super(ContainerReplicator, self).__init__(conf, logger\u003dlogger)"},{"line_number":44,"context_line":"        self.reconciler_cleanups \u003d self.sync_store \u003d None"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def report_up_to_date(self, full_info):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_9d00ac69","line":43,"range":{"start_line":43,"start_character":8,"end_line":43,"end_character":70},"in_reply_to":"5f7c97a3_d4fff131","updated":"2018-05-10 07:50:41.000000000","message":"OK. Done.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def __init__(self, conf, logger\u003dNone):"},{"line_number":43,"context_line":"        super(ContainerReplicator, self).__init__(conf, logger\u003dlogger)"},{"line_number":44,"context_line":"        self.reconciler_cleanups \u003d self.sync_store \u003d None"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def report_up_to_date(self, full_info):"},{"line_number":47,"context_line":"        reported_key_map \u003d {"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_9b5a0f4d","line":44,"range":{"start_line":44,"start_character":35,"end_line":44,"end_character":57},"updated":"2018-05-09 11:33:49.000000000","message":"Just a question. Why not we don\u0027t initiate the sync_store here?\nIt looks like the sync_store is initialized in run_once, then we now have if branch to check the sync_store variable in delete_db.\n\nDoes this work fine?\n\ndiff --git a/swift/container/replicator.py b/swift/container/replicator.py\nindex f58abaf..ec712d0 100644\n--- a/swift/container/replicator.py\n+++ b/swift/container/replicator.py\n@@ -41,7 +41,10 @@ class ContainerReplicator(db_replicator.Replicator):\n \n     def __init__(self, conf, logger\u003dNone):\n         super(ContainerReplicator, self).__init__(conf, logger\u003dlogger)\n-        self.reconciler_cleanups \u003d self.sync_store \u003d None\n+        self.reconciler_cleanups \u003d None\n+        self.sync_store \u003d ContainerSyncStore(self.root,\n+                                             self.logger,\n+                                             self.mount_check)\n \n     def report_up_to_date(self, full_info):\n         reported_key_map \u003d {\n@@ -226,13 +229,12 @@ class ContainerReplicator(db_replicator.Replicator):\n             # this container shouldn\u0027t be here, make sure it\u0027s cleaned up\n             self.reconciler_cleanups[broker.container] \u003d broker\n             return\n-        if self.sync_store:\n-            try:\n-                # DB is going to get deleted. Be preemptive about it\n-                self.sync_store.remove_synced_container(broker)\n-            except Exception:\n-                self.logger.exception(\u0027Failed to remove sync_store entry %s\u0027 %\n-                                      broker.db_file)\n+        try:\n+            # DB is going to get deleted. Be preemptive about it\n+            self.sync_store.remove_synced_container(broker)\n+        except Exception:\n+            self.logger.exception(\u0027Failed to remove sync_store entry %s\u0027 %\n+                                  broker.db_file)\n \n         return super(ContainerReplicator, self).delete_db(broker)\n:","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def __init__(self, conf, logger\u003dNone):"},{"line_number":43,"context_line":"        super(ContainerReplicator, self).__init__(conf, logger\u003dlogger)"},{"line_number":44,"context_line":"        self.reconciler_cleanups \u003d self.sync_store \u003d None"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def report_up_to_date(self, full_info):"},{"line_number":47,"context_line":"        reported_key_map \u003d {"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_8f3160ef","line":44,"range":{"start_line":44,"start_character":35,"end_line":44,"end_character":57},"in_reply_to":"5f7c97a3_9b5a0f4d","updated":"2018-05-09 14:39:21.000000000","message":"The sharder daemon is a subclass of ContainerReplicator but does not require a sync_store instance, so IIRC we either need the condition for using sync_store or we need to override delete_db.\n\nAlso, a sync_store instance initialized in the __init__ would be replaced by a new instance in run_once(), and I don\u0027t want to think about whether it is safe or not to modify run_once to re-use the same sync_store instance.\n\nPerhaps the \u0027ideal\u0027 would be to have a common superclass for the sharder and replicator, but in practice I am not sure the extra layer of class hierarchy would be popular.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":65,"context_line":"        return sync_args"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def _handle_sync_response(self, node, response, info, broker, http,"},{"line_number":68,"context_line":"                              different_region\u003dFalse):"},{"line_number":69,"context_line":"        if is_success(response.status):"},{"line_number":70,"context_line":"            remote_info \u003d json.loads(response.data)"},{"line_number":71,"context_line":"            if incorrect_policy_index(info, remote_info):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_1601f66b","line":68,"range":{"start_line":68,"start_character":46,"end_line":68,"end_character":52},"updated":"2018-05-09 11:33:49.000000000","message":"Just a question. Why the value newly defaulted as False? Exactly it looks no problem if we set False to it by default tho.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":65,"context_line":"        return sync_args"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def _handle_sync_response(self, node, response, info, broker, http,"},{"line_number":68,"context_line":"                              different_region\u003dFalse):"},{"line_number":69,"context_line":"        if is_success(response.status):"},{"line_number":70,"context_line":"            remote_info \u003d json.loads(response.data)"},{"line_number":71,"context_line":"            if incorrect_policy_index(info, remote_info):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_cf6518e3","line":68,"range":{"start_line":68,"start_character":46,"end_line":68,"end_character":52},"in_reply_to":"5f7c97a3_1601f66b","updated":"2018-05-09 14:39:21.000000000","message":"The change makes the method signature consistent with the superclass method that it overrides.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":65,"context_line":"        return sync_args"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    def _handle_sync_response(self, node, response, info, broker, http,"},{"line_number":68,"context_line":"                              different_region\u003dFalse):"},{"line_number":69,"context_line":"        if is_success(response.status):"},{"line_number":70,"context_line":"            remote_info \u003d json.loads(response.data)"},{"line_number":71,"context_line":"            if incorrect_policy_index(info, remote_info):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_bd5fa870","line":68,"range":{"start_line":68,"start_character":46,"end_line":68,"end_character":52},"in_reply_to":"5f7c97a3_cf6518e3","updated":"2018-05-10 07:50:41.000000000","message":"Got it. Thanks. Done.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        return super(ContainerReplicator, self)._handle_sync_response("},{"line_number":82,"context_line":"            node, response, info, broker, http, different_region)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _initialize_broker(self, device, part, account, container, **kwargs):"},{"line_number":85,"context_line":"        hsh \u003d hash_path(account, container)"},{"line_number":86,"context_line":"        db_dir \u003d storage_directory(DATADIR, part, hsh)"},{"line_number":87,"context_line":"        db_path \u003d os.path.join(self.root, device, db_dir, hsh + \u0027.db\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_5b9c77bf","line":84,"range":{"start_line":84,"start_character":67,"end_line":84,"end_character":75},"updated":"2018-05-09 11:33:49.000000000","message":"If we don\u0027t consider to expand this method, perhaps make the argument as broker_init_option that takes a dict, then extracting the dict into the initialize at Line 92 might be easy to understand.\n\n\ndiff --git a/swift/container/replicator.py b/swift/container/replicator.py\nindex f58abaf..c3d1008 100644\n--- a/swift/container/replicator.py\n+++ b/swift/container/replicator.py\n@@ -81,7 +81,20 @@ class ContainerReplicator(db_replicator.Replicator):\n         return super(ContainerReplicator, self)._handle_sync_response(\n             node, response, info, broker, http, different_region)\n \n-    def _initialize_broker(self, device, part, account, container, **kwargs):\n+    def _initialize_broker(\n+            self, device, part, account, container, broker_init_options):\n+        \"\"\"\n+        Create ContainerBroker instance. If the db doesn\u0027t exist, initialize\n+        the db file.\n+\n+        :param device: device path\n+        :param part: partition number\n+        :param accont: account name string\n+        :param container: container name string\n+        :param broker_init_options: a dict to set to\n+            ContainerBroker.initalize method if the db doesn\u0027t exist\n+        :return: ContainerBroker instance\n+        \"\"\"\n         hsh \u003d hash_path(account, container)\n         db_dir \u003d storage_directory(DATADIR, part, hsh)\n         db_path \u003d os.path.join(self.root, device, db_dir, hsh + \u0027.db\u0027)\n@@ -89,7 +102,7 @@ class ContainerReplicator(db_replicator.Replicator):\n                                  logger\u003dself.logger)\n         if not os.path.exists(broker.db_file):\n             try:\n-                broker.initialize(**kwargs)\n+                broker.initialize(**broker_init_options)\n             except DatabaseAlreadyExists:\n                 pass\n         return broker\n@@ -131,7 +144,7 @@ class ContainerReplicator(db_replicator.Replicator):\n                 \u0027container %s in partition %s\u0027 % (container, part))\n         broker \u003d self._initialize_broker(\n             node[\u0027device\u0027], part, account, container,\n-            put_timestamp\u003dtimestamp, storage_policy_index\u003d0)\n+            {\u0027put_timestamp\u0027: timestamp, \u0027storage_policy_index\u0027: 0})\n         if self.reconciler_containers is not None:\n             self.reconciler_containers[container] \u003d part, broker, node[\u0027id\u0027]\n         return broker","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        return super(ContainerReplicator, self)._handle_sync_response("},{"line_number":82,"context_line":"            node, response, info, broker, http, different_region)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _initialize_broker(self, device, part, account, container, **kwargs):"},{"line_number":85,"context_line":"        hsh \u003d hash_path(account, container)"},{"line_number":86,"context_line":"        db_dir \u003d storage_directory(DATADIR, part, hsh)"},{"line_number":87,"context_line":"        db_path \u003d os.path.join(self.root, device, db_dir, hsh + \u0027.db\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_8fc5e05d","line":84,"range":{"start_line":84,"start_character":67,"end_line":84,"end_character":75},"in_reply_to":"5f7c97a3_5b9c77bf","updated":"2018-05-09 14:39:21.000000000","message":"Made all these changes apart from explicitly passing a dict for the kwargs","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        return super(ContainerReplicator, self)._handle_sync_response("},{"line_number":82,"context_line":"            node, response, info, broker, http, different_region)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _initialize_broker(self, device, part, account, container, **kwargs):"},{"line_number":85,"context_line":"        hsh \u003d hash_path(account, container)"},{"line_number":86,"context_line":"        db_dir \u003d storage_directory(DATADIR, part, hsh)"},{"line_number":87,"context_line":"        db_path \u003d os.path.join(self.root, device, db_dir, hsh + \u0027.db\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_3d72b812","line":84,"range":{"start_line":84,"start_character":67,"end_line":84,"end_character":75},"in_reply_to":"5f7c97a3_8fc5e05d","updated":"2018-05-10 07:50:41.000000000","message":"Got it. The change and docs looks reasonable to me.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        :param account: account name string"},{"line_number":93,"context_line":"        :param container: container name string"},{"line_number":94,"context_line":"        :param broker_init_options: keyword arguments to pass to the"},{"line_number":95,"context_line":"            :meth:`swift.container.backend.ContainerBroker.initalize` if the db"},{"line_number":96,"context_line":"            doesn\u0027t exist"},{"line_number":97,"context_line":"        :return: a :class:`swift.container.backend.ContainerBroker` instance"},{"line_number":98,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_3de07896","line":95,"range":{"start_line":95,"start_character":59,"end_line":95,"end_character":68},"updated":"2018-05-10 07:50:41.000000000","message":"sorry, this is from my typo. \"initialize\" correctly.","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84af3b7a5f814809ad669de45a5217dd65ea3925","unresolved":false,"context_lines":[{"line_number":92,"context_line":"        :param account: account name string"},{"line_number":93,"context_line":"        :param container: container name string"},{"line_number":94,"context_line":"        :param broker_init_options: keyword arguments to pass to the"},{"line_number":95,"context_line":"            :meth:`swift.container.backend.ContainerBroker.initalize` if the db"},{"line_number":96,"context_line":"            doesn\u0027t exist"},{"line_number":97,"context_line":"        :return: a :class:`swift.container.backend.ContainerBroker` instance"},{"line_number":98,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_bfe9d7b7","line":95,"range":{"start_line":95,"start_character":59,"end_line":95,"end_character":68},"in_reply_to":"5f7c97a3_3de07896","updated":"2018-05-10 11:20:52.000000000","message":"Done","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            node, response, info, broker, http, different_region)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _initialize_broker(self, device, part, account, container,"},{"line_number":85,"context_line":"                           **broker_init_options):"},{"line_number":86,"context_line":"        \"\"\""},{"line_number":87,"context_line":"        Create a ContainerBroker instance. If the db doesn\u0027t exist, initialize"},{"line_number":88,"context_line":"        the db file."}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_d9af057b","line":85,"updated":"2018-05-10 22:58:32.000000000","message":"It seems kinda weird to hang this off of the replicator... a classmethod on ContainerBroker feels like a more natural place to look for it.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":82,"context_line":"            node, response, info, broker, http, different_region)"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"    def _initialize_broker(self, device, part, account, container,"},{"line_number":85,"context_line":"                           **broker_init_options):"},{"line_number":86,"context_line":"        \"\"\""},{"line_number":87,"context_line":"        Create a ContainerBroker instance. If the db doesn\u0027t exist, initialize"},{"line_number":88,"context_line":"        the db file."}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_21dfd30d","line":85,"in_reply_to":"5f7c97a3_d9af057b","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        the db file."},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        :param device: device path"},{"line_number":91,"context_line":"        :param part: partition number"},{"line_number":92,"context_line":"        :param account: account name string"},{"line_number":93,"context_line":"        :param container: container name string"},{"line_number":94,"context_line":"        :param broker_init_options: keyword arguments to pass to the"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_b9a1e996","line":91,"range":{"start_line":91,"start_character":8,"end_line":91,"end_character":37},"updated":"2018-05-10 22:58:32.000000000","message":"This is determined by (account, container), yeah? Seems weird to have it as an arg...\n\nI suppose it saves us recomputing it for no reason... but we\u0027re *already* recomputing things for no reason with hash_path :-/","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        the db file."},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        :param device: device path"},{"line_number":91,"context_line":"        :param part: partition number"},{"line_number":92,"context_line":"        :param account: account name string"},{"line_number":93,"context_line":"        :param container: container name string"},{"line_number":94,"context_line":"        :param broker_init_options: keyword arguments to pass to the"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_e1e47be2","line":91,"range":{"start_line":91,"start_character":8,"end_line":91,"end_character":37},"in_reply_to":"5f7c97a3_b9a1e996","updated":"2018-05-11 14:26:48.000000000","message":"doesn\u0027t seem so weird to me","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d57fac29389a2cdae651fa42ba581775a7a6ac64","unresolved":false,"context_lines":[{"line_number":88,"context_line":"        the db file."},{"line_number":89,"context_line":""},{"line_number":90,"context_line":"        :param device: device path"},{"line_number":91,"context_line":"        :param part: partition number"},{"line_number":92,"context_line":"        :param account: account name string"},{"line_number":93,"context_line":"        :param container: container name string"},{"line_number":94,"context_line":"        :param broker_init_options: keyword arguments to pass to the"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_7234b593","line":91,"range":{"start_line":91,"start_character":8,"end_line":91,"end_character":37},"in_reply_to":"5f7c97a3_e1e47be2","updated":"2018-05-11 19:48:44.000000000","message":"I just prefer singular sources of truth -- if I go and initialize a broker for a/c on partition 123 but a/c *actually* belongs on partition 456, what happens? I don\u0027t think you\u0027d ever be able to find it from a proxy-server... do we go ahead and replicate it around until someone (container-auditor?) notices that it doesn\u0027t make any sense and quarantines it? What about the work that was already done? Now it\u0027s just *lost*.\n\nWhy allow that to even be expressed?\n\nI\u0027m sure this isn\u0027t the only part of our internal API like this, but it always bugs me a bit when I stumble upon them.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":101,"context_line":"        db_path \u003d os.path.join(self.root, device, db_dir, hsh + \u0027.db\u0027)"},{"line_number":102,"context_line":"        broker \u003d ContainerBroker(db_path, account\u003daccount, container\u003dcontainer,"},{"line_number":103,"context_line":"                                 logger\u003dself.logger)"},{"line_number":104,"context_line":"        if not os.path.exists(broker.db_file):"},{"line_number":105,"context_line":"            try:"},{"line_number":106,"context_line":"                broker.initialize(**broker_init_options)"},{"line_number":107,"context_line":"            except DatabaseAlreadyExists:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_d9fdc56e","line":104,"range":{"start_line":104,"start_character":15,"end_line":104,"end_character":45},"updated":"2018-05-10 22:58:32.000000000","message":"Not\n\n broker._db_exists()\n\n? Not\n\n self._db_file_exists(broker.db_file)\n\n? I don\u0027t have a good feeling for when we want what yet...","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d57fac29389a2cdae651fa42ba581775a7a6ac64","unresolved":false,"context_lines":[{"line_number":101,"context_line":"        db_path \u003d os.path.join(self.root, device, db_dir, hsh + \u0027.db\u0027)"},{"line_number":102,"context_line":"        broker \u003d ContainerBroker(db_path, account\u003daccount, container\u003dcontainer,"},{"line_number":103,"context_line":"                                 logger\u003dself.logger)"},{"line_number":104,"context_line":"        if not os.path.exists(broker.db_file):"},{"line_number":105,"context_line":"            try:"},{"line_number":106,"context_line":"                broker.initialize(**broker_init_options)"},{"line_number":107,"context_line":"            except DatabaseAlreadyExists:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_f2cd2585","line":104,"range":{"start_line":104,"start_character":15,"end_line":104,"end_character":45},"in_reply_to":"5f7c97a3_212d93fd","updated":"2018-05-11 19:48:44.000000000","message":"(This was actually more of a request for a mental model of\n\n- when I should use _db_exists(),\n- when I should use _db_file_exists(file), and\n- when I should just use os.path.exists(file),\n\nbut OK)","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":101,"context_line":"        db_path \u003d os.path.join(self.root, device, db_dir, hsh + \u0027.db\u0027)"},{"line_number":102,"context_line":"        broker \u003d ContainerBroker(db_path, account\u003daccount, container\u003dcontainer,"},{"line_number":103,"context_line":"                                 logger\u003dself.logger)"},{"line_number":104,"context_line":"        if not os.path.exists(broker.db_file):"},{"line_number":105,"context_line":"            try:"},{"line_number":106,"context_line":"                broker.initialize(**broker_init_options)"},{"line_number":107,"context_line":"            except DatabaseAlreadyExists:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_212d93fd","line":104,"range":{"start_line":104,"start_character":15,"end_line":104,"end_character":45},"in_reply_to":"5f7c97a3_d9fdc56e","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"}],"swift/container/server.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":359,"context_line":"                created \u003d True"},{"line_number":360,"context_line":"        if not os.path.exists(broker.db_file):"},{"line_number":361,"context_line":"            raise HTTPNotFound()"},{"line_number":362,"context_line":"        return created"},{"line_number":363,"context_line":""},{"line_number":364,"context_line":"    def _update_metadata(self, req, broker, req_timestamp, method):"},{"line_number":365,"context_line":"        metadata \u003d {}"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_6afe3a38","line":362,"range":{"start_line":362,"start_character":8,"end_line":362,"end_character":22},"updated":"2018-05-09 11:33:49.000000000","message":"I wondered why we need to return unused bool here but the latter patch looks to use it to handle the HTTP Response.\n\nI\u0027m still thinking of the difference of _maybe_autocreate and _update_or_create. autocraete seems like a part of _update_or_create but... hmm.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":359,"context_line":"                created \u003d True"},{"line_number":360,"context_line":"        if not os.path.exists(broker.db_file):"},{"line_number":361,"context_line":"            raise HTTPNotFound()"},{"line_number":362,"context_line":"        return created"},{"line_number":363,"context_line":""},{"line_number":364,"context_line":"    def _update_metadata(self, req, broker, req_timestamp, method):"},{"line_number":365,"context_line":"        metadata \u003d {}"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_6fade486","line":362,"range":{"start_line":362,"start_character":8,"end_line":362,"end_character":22},"in_reply_to":"5f7c97a3_6afe3a38","updated":"2018-05-09 14:39:21.000000000","message":"https://review.openstack.org/#/c/565745/3/swift/container/server.py@426","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":359,"context_line":"                created \u003d True"},{"line_number":360,"context_line":"        if not os.path.exists(broker.db_file):"},{"line_number":361,"context_line":"            raise HTTPNotFound()"},{"line_number":362,"context_line":"        return created"},{"line_number":363,"context_line":""},{"line_number":364,"context_line":"    def _update_metadata(self, req, broker, req_timestamp, method):"},{"line_number":365,"context_line":"        metadata \u003d {}"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_9db8ac76","line":362,"range":{"start_line":362,"start_character":8,"end_line":362,"end_character":22},"in_reply_to":"5f7c97a3_6fade486","updated":"2018-05-10 07:50:41.000000000","message":"Yeah, I saw that. Just I\u0027m still thinking of cleanup/encapsulation  for db initialization because it seems that _maybe_autocreate, _update_or_create, and _initalize_broker use similar code (i.e. path check, attempt to create if not exist, etc...) but for now, I don\u0027t have better concrete code so we can leave them as they are, then consider the refactoring later.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"}],"test/__init__.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":93,"context_line":""},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"@contextmanager"},{"line_number":96,"context_line":"def annotate_failure(msg):"},{"line_number":97,"context_line":"    \"\"\""},{"line_number":98,"context_line":"    Catch AssertionError and annotate it with a message. Useful when making"},{"line_number":99,"context_line":"    assertions in a loop where the message can indicate the loop index or"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_2d8b7c1f","line":96,"range":{"start_line":96,"start_character":0,"end_line":96,"end_character":26},"updated":"2018-05-09 11:33:49.000000000","message":"OK. This is not used in this patch but used in the latter patches. And the purpose and code looks good to me.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"}],"test/probe/brain.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        self.part, self.nodes \u003d self.ring.get_nodes(self.account, c, o)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        node_ids \u003d [n[\u0027id\u0027] for n in self.nodes]"},{"line_number":105,"context_line":"        self.node_numbers \u003d [n + 1 for n in node_ids]"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        if all(n_id in node_ids for n_id in (0, 1)):"},{"line_number":108,"context_line":"            self.primary_numbers \u003d (1, 2)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_4d66f853","line":105,"range":{"start_line":105,"start_character":29,"end_line":105,"end_character":36},"updated":"2018-05-09 11:33:49.000000000","message":"why do we need to increment the node id for each here? That looks just a node id + 1 list...","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        self.part, self.nodes \u003d self.ring.get_nodes(self.account, c, o)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        node_ids \u003d [n[\u0027id\u0027] for n in self.nodes]"},{"line_number":105,"context_line":"        self.node_numbers \u003d [n + 1 for n in node_ids]"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        if all(n_id in node_ids for n_id in (0, 1)):"},{"line_number":108,"context_line":"            self.primary_numbers \u003d (1, 2)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_4ff4a85b","line":105,"range":{"start_line":105,"start_character":29,"end_line":105,"end_character":36},"in_reply_to":"5f7c97a3_4d66f853","updated":"2018-05-09 14:39:21.000000000","message":"this is just for convenience","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84af3b7a5f814809ad669de45a5217dd65ea3925","unresolved":false,"context_lines":[{"line_number":102,"context_line":"        self.part, self.nodes \u003d self.ring.get_nodes(self.account, c, o)"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"        node_ids \u003d [n[\u0027id\u0027] for n in self.nodes]"},{"line_number":105,"context_line":"        self.node_numbers \u003d [n + 1 for n in node_ids]"},{"line_number":106,"context_line":""},{"line_number":107,"context_line":"        if all(n_id in node_ids for n_id in (0, 1)):"},{"line_number":108,"context_line":"            self.primary_numbers \u003d (1, 2)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_d98b931c","line":105,"range":{"start_line":105,"start_character":29,"end_line":105,"end_character":36},"in_reply_to":"5f7c97a3_4ff4a85b","updated":"2018-05-10 11:20:52.000000000","message":"by \u0027convenience\u0027 I mean it simply saves having to increment the node id every time we want a number to pass to the brain.servers start/stop methods","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        else:"},{"line_number":111,"context_line":"            self.primary_numbers \u003d (3, 4)"},{"line_number":112,"context_line":"            self.handoff_numbers \u003d (1, 2)"},{"line_number":113,"context_line":"        self.nodes_by_number \u003d dict((node[\u0027id\u0027] + 1, node)"},{"line_number":114,"context_line":"                                    for node in self.nodes)"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    @command"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_edd104cf","line":113,"updated":"2018-05-09 11:33:49.000000000","message":"Same here. If you want the index in the node_number list, just\n\n dict((index, node) for index, node in enumerate(self.nodes))\n\nwould be fine?","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        else:"},{"line_number":111,"context_line":"            self.primary_numbers \u003d (3, 4)"},{"line_number":112,"context_line":"            self.handoff_numbers \u003d (1, 2)"},{"line_number":113,"context_line":"        self.nodes_by_number \u003d dict((node[\u0027id\u0027] + 1, node)"},{"line_number":114,"context_line":"                                    for node in self.nodes)"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    @command"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_c54e4a6e","line":113,"in_reply_to":"5f7c97a3_2f960cf2","updated":"2018-05-10 07:50:41.000000000","message":"Basically, I don\u0027t have strong opinion but felt weird.\nthe node ids are not guaranteed to be sequential, right?\nso node_numbers would be like\n\n node_ids: [3, 1, 4] (3x replica)\n node_numbers: [4, 2, 5]\n nodes_by_number: {4:3, 2:1, 5:4}\n\nSo the means of node_numbers is... what? Am I missing something?","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84af3b7a5f814809ad669de45a5217dd65ea3925","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        else:"},{"line_number":111,"context_line":"            self.primary_numbers \u003d (3, 4)"},{"line_number":112,"context_line":"            self.handoff_numbers \u003d (1, 2)"},{"line_number":113,"context_line":"        self.nodes_by_number \u003d dict((node[\u0027id\u0027] + 1, node)"},{"line_number":114,"context_line":"                                    for node in self.nodes)"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    @command"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_39c4075f","line":113,"in_reply_to":"5f7c97a3_c54e4a6e","updated":"2018-05-10 11:20:52.000000000","message":"ok, I looked at where this used in later patch and it seems unnecessary, and is also obviously confusing. I will remove it and re-work the probe tests.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":110,"context_line":"        else:"},{"line_number":111,"context_line":"            self.primary_numbers \u003d (3, 4)"},{"line_number":112,"context_line":"            self.handoff_numbers \u003d (1, 2)"},{"line_number":113,"context_line":"        self.nodes_by_number \u003d dict((node[\u0027id\u0027] + 1, node)"},{"line_number":114,"context_line":"                                    for node in self.nodes)"},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"    @command"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_2f960cf2","line":113,"in_reply_to":"5f7c97a3_edd104cf","updated":"2018-05-09 14:39:21.000000000","message":"agree but it\u0027s a little more obvious that the keys are the node_numbers? IDK?","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":109,"context_line":"            self.handoff_numbers \u003d (3, 4)"},{"line_number":110,"context_line":"        else:"},{"line_number":111,"context_line":"            self.primary_numbers \u003d (3, 4)"},{"line_number":112,"context_line":"            self.handoff_numbers \u003d (1, 2)"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    @command"},{"line_number":115,"context_line":"    def start_primary_half(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_79f83148","line":112,"updated":"2018-05-10 22:58:32.000000000","message":"Maybe more obvious as\n\n        self.node_numbers \u003d [n[\u0027id\u0027] + 1 for n in self.nodes]\n        if 1 in self.node_numbers and 2 in self.node_numbers:\n            self.primary_numbers \u003d (1, 2)\n            self.handoff_numbers \u003d (3, 4)\n        else:\n            self.primary_numbers \u003d (3, 4)\n            self.handoff_numbers \u003d (1, 2)\n\nand we get rid of node_ids entirely.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":109,"context_line":"            self.handoff_numbers \u003d (3, 4)"},{"line_number":110,"context_line":"        else:"},{"line_number":111,"context_line":"            self.primary_numbers \u003d (3, 4)"},{"line_number":112,"context_line":"            self.handoff_numbers \u003d (1, 2)"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    @command"},{"line_number":115,"context_line":"    def start_primary_half(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_c13dbf2b","line":112,"in_reply_to":"5f7c97a3_79f83148","updated":"2018-05-11 14:26:48.000000000","message":"follow up","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e8917b8e03fe4ee4dfb424e1b572a9c1b3e799f1","unresolved":false,"context_lines":[{"line_number":109,"context_line":"            self.handoff_numbers \u003d (3, 4)"},{"line_number":110,"context_line":"        else:"},{"line_number":111,"context_line":"            self.primary_numbers \u003d (3, 4)"},{"line_number":112,"context_line":"            self.handoff_numbers \u003d (1, 2)"},{"line_number":113,"context_line":""},{"line_number":114,"context_line":"    @command"},{"line_number":115,"context_line":"    def start_primary_half(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_75c25f5b","line":112,"in_reply_to":"5f7c97a3_c13dbf2b","updated":"2018-05-11 20:26:45.000000000","message":"Proposed against master: https://review.openstack.org/567940","commit_id":"1815146a149a51ec759399986846f1962363b0e8"}],"test/probe/common.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":506,"context_line":"        all_obj_nodes \u003d {}"},{"line_number":507,"context_line":"        for policy in ENABLED_POLICIES:"},{"line_number":508,"context_line":"            for dev in policy.object_ring.devs:"},{"line_number":509,"context_line":"                all_obj_nodes[dev[\u0027device\u0027]] \u003d dev"},{"line_number":510,"context_line":"        return all_obj_nodes.values()"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"    def gather_async_pendings(self, onodes):"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_d2ec0a2b","line":509,"range":{"start_line":509,"start_character":30,"end_line":509,"end_character":43},"updated":"2018-05-08 00:03:33.000000000","message":"I worry a little about the possibility of a collision here with slightly different dev dicts... Like, would it ever make sense for two policies to share the same device but use two separate object-server processes listening on different ports? IDK... probably unfounded concern...","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":518,"context_line":"        \"\"\""},{"line_number":519,"context_line":"        async_pendings \u003d []"},{"line_number":520,"context_line":"        for onode in onodes:"},{"line_number":521,"context_line":"            device_dir \u003d self.device_dir(\u0027\u0027, onode)"},{"line_number":522,"context_line":"            for ap_pol_dir in os.listdir(device_dir):"},{"line_number":523,"context_line":"                if not ap_pol_dir.startswith(\u0027async_pending\u0027):"},{"line_number":524,"context_line":"                    # skip \u0027objects\u0027, \u0027containers\u0027, etc."}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_92f692f9","line":521,"range":{"start_line":521,"start_character":41,"end_line":521,"end_character":43},"updated":"2018-05-08 00:03:33.000000000","message":"?","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":518,"context_line":"        \"\"\""},{"line_number":519,"context_line":"        async_pendings \u003d []"},{"line_number":520,"context_line":"        for onode in onodes:"},{"line_number":521,"context_line":"            device_dir \u003d self.device_dir(\u0027\u0027, onode)"},{"line_number":522,"context_line":"            for ap_pol_dir in os.listdir(device_dir):"},{"line_number":523,"context_line":"                if not ap_pol_dir.startswith(\u0027async_pending\u0027):"},{"line_number":524,"context_line":"                    # skip \u0027objects\u0027, \u0027containers\u0027, etc."}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_8e3181a5","line":521,"range":{"start_line":521,"start_character":41,"end_line":521,"end_character":43},"in_reply_to":"5f7c97a3_92f692f9","updated":"2018-05-08 12:44:19.000000000","message":"this method was simply moved from test_object_expirer.py. The first arg passed to device_dir is unused, an existing \u0027bug\u0027, but that method is called from sufficient places that I don\u0027t want to introduce noise by fixing it here.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"9cdb9c50b539cddf9dcd733d4df2b8b712e5a786","unresolved":false,"context_lines":[{"line_number":527,"context_line":"                try:"},{"line_number":528,"context_line":"                    ap_dirs \u003d os.listdir(async_pending_dir)"},{"line_number":529,"context_line":"                except OSError as err:"},{"line_number":530,"context_line":"                    if err.errno \u003d\u003d errno.ENOENT:"},{"line_number":531,"context_line":"                        pass"},{"line_number":532,"context_line":"                    else:"},{"line_number":533,"context_line":"                        raise"},{"line_number":534,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_72cc16bc","line":531,"range":{"start_line":530,"start_character":20,"end_line":531,"end_character":28},"updated":"2018-05-08 00:03:33.000000000","message":"Have we seen this come up in practice? I\u0027d hope that at whatever point we\u0027d call gather_async_pendings all of our swift processes would have settled, and there shouldn\u0027t be concurrent changes to the filesystem...","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":527,"context_line":"                try:"},{"line_number":528,"context_line":"                    ap_dirs \u003d os.listdir(async_pending_dir)"},{"line_number":529,"context_line":"                except OSError as err:"},{"line_number":530,"context_line":"                    if err.errno \u003d\u003d errno.ENOENT:"},{"line_number":531,"context_line":"                        pass"},{"line_number":532,"context_line":"                    else:"},{"line_number":533,"context_line":"                        raise"},{"line_number":534,"context_line":"                else:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_8ed66127","line":531,"range":{"start_line":530,"start_character":20,"end_line":531,"end_character":28},"in_reply_to":"5f7c97a3_72cc16bc","updated":"2018-05-08 12:44:19.000000000","message":"out of scope, method was simply relocated.","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":506,"context_line":"        all_obj_nodes \u003d {}"},{"line_number":507,"context_line":"        for policy in ENABLED_POLICIES:"},{"line_number":508,"context_line":"            for dev in policy.object_ring.devs:"},{"line_number":509,"context_line":"                all_obj_nodes[dev[\u0027device\u0027]] \u003d dev"},{"line_number":510,"context_line":"        return all_obj_nodes.values()"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"    def gather_async_pendings(self, onodes):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_cd20c8b3","line":509,"updated":"2018-05-09 11:33:49.000000000","message":"It might be safe in the prob tests world but I\u0027m worried about the overwritten if rings are set up using same device but different ports.\n\nThat would make the latter ones are winers.\n\nAh... I noticed this is just moved from test_object_expirer.py so that would be existing issue at the master.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":507,"context_line":"        for policy in ENABLED_POLICIES:"},{"line_number":508,"context_line":"            for dev in policy.object_ring.devs:"},{"line_number":509,"context_line":"                all_obj_nodes[dev[\u0027device\u0027]] \u003d dev"},{"line_number":510,"context_line":"        return all_obj_nodes.values()"},{"line_number":511,"context_line":""},{"line_number":512,"context_line":"    def gather_async_pendings(self, onodes):"},{"line_number":513,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_7c301fe9","line":510,"updated":"2018-05-10 22:58:32.000000000","message":"Off-topic: eventually, we\u0027ll want this to be\n\n return list(all_obj_nodes.values())\n\nbecause py3.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"}],"test/unit/__init__.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":751,"context_line":"        :param response_sleep: float, time to eventlet sleep during response"},{"line_number":752,"context_line":"        \"\"\""},{"line_number":753,"context_line":"        # connect exception"},{"line_number":754,"context_line":"        if inspect.isclass(status) and issubclass(status, Exception):"},{"line_number":755,"context_line":"            raise status(\u0027FakeStatus Error\u0027)"},{"line_number":756,"context_line":"        if isinstance(status, (Exception, eventlet.Timeout)):"},{"line_number":757,"context_line":"            raise status"},{"line_number":758,"context_line":"        if isinstance(status, tuple):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_e0b6ebfa","line":755,"range":{"start_line":754,"start_character":0,"end_line":755,"end_character":44},"updated":"2018-05-09 11:33:49.000000000","message":"memo) will be back to know what\u0027s this.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84af3b7a5f814809ad669de45a5217dd65ea3925","unresolved":false,"context_lines":[{"line_number":751,"context_line":"        :param response_sleep: float, time to eventlet sleep during response"},{"line_number":752,"context_line":"        \"\"\""},{"line_number":753,"context_line":"        # connect exception"},{"line_number":754,"context_line":"        if inspect.isclass(status) and issubclass(status, Exception):"},{"line_number":755,"context_line":"            raise status(\u0027FakeStatus Error\u0027)"},{"line_number":756,"context_line":"        if isinstance(status, (Exception, eventlet.Timeout)):"},{"line_number":757,"context_line":"            raise status"},{"line_number":758,"context_line":"        if isinstance(status, tuple):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_dfde1310","line":755,"range":{"start_line":754,"start_character":0,"end_line":755,"end_character":44},"in_reply_to":"5f7c97a3_08053714","updated":"2018-05-10 11:20:52.000000000","message":"yes, sorry, I used a bad example","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":751,"context_line":"        :param response_sleep: float, time to eventlet sleep during response"},{"line_number":752,"context_line":"        \"\"\""},{"line_number":753,"context_line":"        # connect exception"},{"line_number":754,"context_line":"        if inspect.isclass(status) and issubclass(status, Exception):"},{"line_number":755,"context_line":"            raise status(\u0027FakeStatus Error\u0027)"},{"line_number":756,"context_line":"        if isinstance(status, (Exception, eventlet.Timeout)):"},{"line_number":757,"context_line":"            raise status"},{"line_number":758,"context_line":"        if isinstance(status, tuple):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_08053714","line":755,"range":{"start_line":754,"start_character":0,"end_line":755,"end_character":44},"in_reply_to":"5f7c97a3_0fd550b9","updated":"2018-05-10 07:50:41.000000000","message":"I think http status should be set by status int. WIth the comment above \"# connect exception\", it seems like to be expected to be used to simulate sort of non-HTTP response. e.g. socket error. Anyway, it looks to be not a problem so it\u0027s ok to be as is.","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5000cac6e4ab4e020e57229b91e9bc74337c3c1e","unresolved":false,"context_lines":[{"line_number":751,"context_line":"        :param response_sleep: float, time to eventlet sleep during response"},{"line_number":752,"context_line":"        \"\"\""},{"line_number":753,"context_line":"        # connect exception"},{"line_number":754,"context_line":"        if inspect.isclass(status) and issubclass(status, Exception):"},{"line_number":755,"context_line":"            raise status(\u0027FakeStatus Error\u0027)"},{"line_number":756,"context_line":"        if isinstance(status, (Exception, eventlet.Timeout)):"},{"line_number":757,"context_line":"            raise status"},{"line_number":758,"context_line":"        if isinstance(status, tuple):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_0fd550b9","line":755,"range":{"start_line":754,"start_character":0,"end_line":755,"end_character":44},"in_reply_to":"5f7c97a3_e0b6ebfa","updated":"2018-05-09 14:39:21.000000000","message":"Clay added this but IIUC it allows an exception class to be passed as well as an instance of the exception class. So\n\n  FakeStatus(HTTPNotFound)\n\nworks as well as:\n\n  FakeStatus(HTTPNotFound())","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1067,"context_line":""},{"line_number":1068,"context_line":"@contextmanager"},{"line_number":1069,"context_line":"def mock_timestamp_now(now\u003dNone):"},{"line_number":1070,"context_line":"    now \u003d now or Timestamp.now()"},{"line_number":1071,"context_line":"    with mocklib.patch(\u0027swift.common.utils.Timestamp.now\u0027,"},{"line_number":1072,"context_line":"                       classmethod(lambda c: now)):"},{"line_number":1073,"context_line":"        yield now"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_9cb09b45","line":1070,"updated":"2018-05-10 22:58:32.000000000","message":"Probably want\n\n if now is None:\n     now \u003d Timestamp.now()\n\nso we don\u0027t curse ourselves after writing\n\n with mock_timestamp_now(0):\n     # start messing with Timestamp(1) expecting it to be in the future","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1067,"context_line":""},{"line_number":1068,"context_line":"@contextmanager"},{"line_number":1069,"context_line":"def mock_timestamp_now(now\u003dNone):"},{"line_number":1070,"context_line":"    now \u003d now or Timestamp.now()"},{"line_number":1071,"context_line":"    with mocklib.patch(\u0027swift.common.utils.Timestamp.now\u0027,"},{"line_number":1072,"context_line":"                       classmethod(lambda c: now)):"},{"line_number":1073,"context_line":"        yield now"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_2116f3a9","line":1070,"in_reply_to":"5f7c97a3_9cb09b45","updated":"2018-05-11 14:26:48.000000000","message":"good point","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1341,"context_line":"            os.unlink(path)"},{"line_number":1342,"context_line":"        except OSError as err:"},{"line_number":1343,"context_line":"            if err \u003d\u003d errno.ENOENT:"},{"line_number":1344,"context_line":"                pass"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_3c8b876e","line":1344,"updated":"2018-05-10 22:58:32.000000000","message":"Do we mean to say\n\n if err.errno !\u003d errno.ENOENT:\n     raise\n\n? As it is, the if clause is trivially false but that doesn\u0027t matter because the whole except block is a no-op.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1341,"context_line":"            os.unlink(path)"},{"line_number":1342,"context_line":"        except OSError as err:"},{"line_number":1343,"context_line":"            if err \u003d\u003d errno.ENOENT:"},{"line_number":1344,"context_line":"                pass"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_811ca7c1","line":1344,"in_reply_to":"5f7c97a3_3c8b876e","updated":"2018-05-11 14:26:48.000000000","message":"yes that would make more sense!","commit_id":"1815146a149a51ec759399986846f1962363b0e8"}],"test/unit/common/test_db.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"6fa2c2e70720f874ce39d4221611013898a7bb7f","unresolved":false,"context_lines":[{"line_number":1493,"context_line":"            pass"},{"line_number":1494,"context_line":"        with patch.object(broker, \u0027_commit_puts\u0027) as mock_commit_puts:"},{"line_number":1495,"context_line":"            with self.assertRaises(DatabaseConnectionError) as cm:"},{"line_number":1496,"context_line":"                broker.put_record(\u0027unwelcome\u0027)"},{"line_number":1497,"context_line":"        self.assertIn(\u0027commits not accepted\u0027, str(cm.exception))"},{"line_number":1498,"context_line":"        mock_commit_puts.assert_not_called()"},{"line_number":1499,"context_line":"        with open(broker.pending_file, \u0027rb\u0027) as fd:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_354443b7","line":1496,"updated":"2018-05-08 10:11:34.000000000","message":"As I asked in the swift/common/db.py, I didn\u0027t get how useful this is yet. it looks like not a skip_commits but read_only DB Broker? That is because no record can be put within the DB...","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d2767fc9dba356e27260488b971de87018a11b52","unresolved":false,"context_lines":[{"line_number":1493,"context_line":"            pass"},{"line_number":1494,"context_line":"        with patch.object(broker, \u0027_commit_puts\u0027) as mock_commit_puts:"},{"line_number":1495,"context_line":"            with self.assertRaises(DatabaseConnectionError) as cm:"},{"line_number":1496,"context_line":"                broker.put_record(\u0027unwelcome\u0027)"},{"line_number":1497,"context_line":"        self.assertIn(\u0027commits not accepted\u0027, str(cm.exception))"},{"line_number":1498,"context_line":"        mock_commit_puts.assert_not_called()"},{"line_number":1499,"context_line":"        with open(broker.pending_file, \u0027rb\u0027) as fd:"}],"source_content_type":"text/x-python","patch_set":1,"id":"5f7c97a3_4eae0999","line":1496,"in_reply_to":"5f7c97a3_354443b7","updated":"2018-05-08 12:44:19.000000000","message":"I will remove this","commit_id":"f5a7acaa7f8d732c8e5b2ea69cdda2118b8700af"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":315,"context_line":""},{"line_number":316,"context_line":"    def is_reclaimable(self, now, reclaim_age):"},{"line_number":317,"context_line":"        info \u003d self.get_replication_info()"},{"line_number":318,"context_line":"        return (info[\u0027count\u0027] in (None, \u0027\u0027, 0, \u00270\u0027)) and \\"},{"line_number":319,"context_line":"            (Timestamp(now - reclaim_age) \u003e"},{"line_number":320,"context_line":"             Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":321,"context_line":"             Timestamp(info[\u0027put_timestamp\u0027]))"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_0b9c5168","line":318,"range":{"start_line":318,"start_character":16,"end_line":318,"end_character":52},"updated":"2018-05-10 07:50:41.000000000","message":"please use zero_like.","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84af3b7a5f814809ad669de45a5217dd65ea3925","unresolved":false,"context_lines":[{"line_number":315,"context_line":""},{"line_number":316,"context_line":"    def is_reclaimable(self, now, reclaim_age):"},{"line_number":317,"context_line":"        info \u003d self.get_replication_info()"},{"line_number":318,"context_line":"        return (info[\u0027count\u0027] in (None, \u0027\u0027, 0, \u00270\u0027)) and \\"},{"line_number":319,"context_line":"            (Timestamp(now - reclaim_age) \u003e"},{"line_number":320,"context_line":"             Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":321,"context_line":"             Timestamp(info[\u0027put_timestamp\u0027]))"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_9f32db5d","line":318,"range":{"start_line":318,"start_character":16,"end_line":318,"end_character":52},"in_reply_to":"5f7c97a3_0b9c5168","updated":"2018-05-10 11:20:52.000000000","message":"Done","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":1480,"context_line":"        # pending file above cap"},{"line_number":1481,"context_line":"        cap \u003d swift.common.db.PENDING_CAP"},{"line_number":1482,"context_line":"        while os.path.getsize(broker.pending_file) \u003c cap:"},{"line_number":1483,"context_line":"            with open(broker.pending_file, \u0027ab\u0027) as fd:"},{"line_number":1484,"context_line":"                fd.write(\u0027x\u0027 * 100000)"},{"line_number":1485,"context_line":"        with patch.object(broker, \u0027_commit_puts\u0027) as mock_commit_puts:"},{"line_number":1486,"context_line":"            broker.put_record(\u0027direct\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_ee056312","line":1483,"range":{"start_line":1483,"start_character":43,"end_line":1483,"end_character":47},"updated":"2018-05-10 07:50:41.000000000","message":"This is append mode so I thought this while loop append \u0027x\u0027 to the PINKY, PERKEY in the pending file... ah, OK, that should happen in the _commit_puts that is mocked at L1485. Got it.","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        return (zero_like(info[\u0027count\u0027]) and"},{"line_number":319,"context_line":"                (Timestamp(now - reclaim_age) \u003e"},{"line_number":320,"context_line":"                 Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":321,"context_line":"                 Timestamp(info[\u0027put_timestamp\u0027])))"},{"line_number":322,"context_line":""},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"class TestExampleBroker(unittest.TestCase):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_fc2aef29","line":321,"updated":"2018-05-10 22:58:32.000000000","message":"Why don\u0027t we just put this implementation in DatabaseBroker so this and AccountBroker get it for free, and let ContainerBroker override it?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        return (zero_like(info[\u0027count\u0027]) and"},{"line_number":319,"context_line":"                (Timestamp(now - reclaim_age) \u003e"},{"line_number":320,"context_line":"                 Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":321,"context_line":"                 Timestamp(info[\u0027put_timestamp\u0027])))"},{"line_number":322,"context_line":""},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"class TestExampleBroker(unittest.TestCase):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_90b3974d","line":321,"in_reply_to":"5f7c97a3_fc2aef29","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1030,"context_line":"        broker.merge_syncs([{\u0027sync_point\u0027: -1, \u0027remote_id\u0027: uuid2},"},{"line_number":1031,"context_line":"                            {\u0027sync_point\u0027: 3, \u0027remote_id\u0027: uuid3}])"},{"line_number":1032,"context_line":"        self.assertEqual(broker.get_sync(uuid2), 5)"},{"line_number":1033,"context_line":"        self.assertEqual(broker.get_sync(uuid3), 3)"},{"line_number":1034,"context_line":""},{"line_number":1035,"context_line":"    def test_get_replication_info(self):"},{"line_number":1036,"context_line":"        self.get_replication_info_tester(metadata\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_bce5570b","line":1033,"updated":"2018-05-10 22:58:32.000000000","message":"Worth having assertions that the outgoing syncs are untouched?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1030,"context_line":"        broker.merge_syncs([{\u0027sync_point\u0027: -1, \u0027remote_id\u0027: uuid2},"},{"line_number":1031,"context_line":"                            {\u0027sync_point\u0027: 3, \u0027remote_id\u0027: uuid3}])"},{"line_number":1032,"context_line":"        self.assertEqual(broker.get_sync(uuid2), 5)"},{"line_number":1033,"context_line":"        self.assertEqual(broker.get_sync(uuid3), 3)"},{"line_number":1034,"context_line":""},{"line_number":1035,"context_line":"    def test_get_replication_info(self):"},{"line_number":1036,"context_line":"        self.get_replication_info_tester(metadata\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_f0da0b49","line":1033,"in_reply_to":"5f7c97a3_bce5570b","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1135,"context_line":"        def reclaim(broker, timestamp):"},{"line_number":1136,"context_line":"            # only testing _reclaim_metadata here"},{"line_number":1137,"context_line":"            with patch.object(broker, \u0027_reclaim\u0027):"},{"line_number":1138,"context_line":"                broker.reclaim(timestamp, timestamp)"},{"line_number":1139,"context_line":"        # Initializes a good broker for us"},{"line_number":1140,"context_line":"        broker \u003d self.get_replication_info_tester(metadata\u003dTrue)"},{"line_number":1141,"context_line":"        # Add our first item"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_5cd8c31c","line":1138,"updated":"2018-05-10 22:58:32.000000000","message":"Could just do this throughout the test:\n\n diff --git a/test/unit/common/test_db.py b/test/unit/common/test_db.py\n index 4decf05ca..ea557b736 100644\n --- a/test/unit/common/test_db.py\n +++ b/test/unit/common/test_db.py\n @@ -1131,11 +1131,9 @@ class TestDatabaseBroker(unittest.TestCase):\n              \u0027max_row\u0027: 1, \u0027id\u0027: broker_uuid, \u0027metadata\u0027: broker_metadata})\n          return broker\n  \n -    def test_metadata(self):\n -        def reclaim(broker, timestamp):\n -            # only testing _reclaim_metadata here\n -            with patch.object(broker, \u0027_reclaim\u0027):\n -                broker.reclaim(timestamp, timestamp)\n +    # only testing _reclaim_metadata here\n +    @patch.object(DatabaseBroker, \u0027_reclaim\u0027)\n +    def test_metadata(self, mock_reclaim):\n          # Initializes a good broker for us\n          broker \u003d self.get_replication_info_tester(metadata\u003dTrue)\n          # Add our first item\n @@ -1176,7 +1174,7 @@ class TestDatabaseBroker(unittest.TestCase):\n          self.assertEqual(broker.metadata[\u0027Second\u0027],\n                           [second_value, second_timestamp])\n          # Reclaim at point before second item was deleted\n -        reclaim(broker, normalize_timestamp(3))\n +        broker.reclaim(normalize_timestamp(3), normalize_timestamp(3))\n          self.assertIn(\u0027First\u0027, broker.metadata)\n          self.assertEqual(broker.metadata[\u0027First\u0027],\n                           [first_value, first_timestamp])\n @@ -1184,7 +1182,7 @@ class TestDatabaseBroker(unittest.TestCase):\n          self.assertEqual(broker.metadata[\u0027Second\u0027],\n                           [second_value, second_timestamp])\n          # Reclaim at point second item was deleted\n -        reclaim(broker, normalize_timestamp(4))\n +        broker.reclaim(normalize_timestamp(4), normalize_timestamp(4))\n          self.assertIn(\u0027First\u0027, broker.metadata)\n          self.assertEqual(broker.metadata[\u0027First\u0027],\n                           [first_value, first_timestamp])\n @@ -1192,7 +1190,7 @@ class TestDatabaseBroker(unittest.TestCase):\n          self.assertEqual(broker.metadata[\u0027Second\u0027],\n                           [second_value, second_timestamp])\n          # Reclaim after point second item was deleted\n -        reclaim(broker, normalize_timestamp(5))\n +        broker.reclaim(normalize_timestamp(5), normalize_timestamp(5))\n          self.assertIn(\u0027First\u0027, broker.metadata)\n          self.assertEqual(broker.metadata[\u0027First\u0027],\n                           [first_value, first_timestamp])\n\nMight also be nice to have some tests with a difference between age_timestamp and sync_timestamp.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1135,"context_line":"        def reclaim(broker, timestamp):"},{"line_number":1136,"context_line":"            # only testing _reclaim_metadata here"},{"line_number":1137,"context_line":"            with patch.object(broker, \u0027_reclaim\u0027):"},{"line_number":1138,"context_line":"                broker.reclaim(timestamp, timestamp)"},{"line_number":1139,"context_line":"        # Initializes a good broker for us"},{"line_number":1140,"context_line":"        broker \u003d self.get_replication_info_tester(metadata\u003dTrue)"},{"line_number":1141,"context_line":"        # Add our first item"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_0bb516cd","line":1138,"in_reply_to":"5f7c97a3_5cd8c31c","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1245,"context_line":"        self.assertEqual("},{"line_number":1246,"context_line":"            str(exc),"},{"line_number":1247,"context_line":"            \u0027Quarantined %s to %s due to missing row in container_stat table\u0027 %"},{"line_number":1248,"context_line":"            (dbpath, qpath))"},{"line_number":1249,"context_line":""},{"line_number":1250,"context_line":"    @patch.object(DatabaseBroker, \u0027validate_metadata\u0027)"},{"line_number":1251,"context_line":"    def test_validate_metadata_is_called_from_update_metadata(self, mock):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_5cfbe345","line":1248,"updated":"2018-05-10 22:58:32.000000000","message":"Off-topic: better as\n\n diff --git a/test/unit/common/test_db.py b/test/unit/common/test_db.py\n index 4decf05ca..604e37b45 100644\n --- a/test/unit/common/test_db.py\n +++ b/test/unit/common/test_db.py\n @@ -1236,14 +1236,11 @@ class TestDatabaseBroker(unittest.TestCase):\n          broker \u003d DatabaseBroker(os.path.join(dbpath, \u00271.db\u0027))\n          broker.db_type \u003d \u0027container\u0027\n  \n -        exc \u003d None\n -        try:\n -            with broker.get() as conn:\n -                broker._reclaim_metadata(conn, 0)\n -        except Exception as err:\n -            exc \u003d err\n +        with self.assertRaises(sqlite3.DatabaseError) as raised, \\\n +                broker.get() as conn:\n +            broker._reclaim_metadata(conn, 0)\n          self.assertEqual(\n -            str(exc),\n +            str(raised.exception),\n              \u0027Quarantined %s to %s due to missing row in container_stat table\u0027 %\n              (dbpath, qpath))","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"e8917b8e03fe4ee4dfb424e1b572a9c1b3e799f1","unresolved":false,"context_lines":[{"line_number":1245,"context_line":"        self.assertEqual("},{"line_number":1246,"context_line":"            str(exc),"},{"line_number":1247,"context_line":"            \u0027Quarantined %s to %s due to missing row in container_stat table\u0027 %"},{"line_number":1248,"context_line":"            (dbpath, qpath))"},{"line_number":1249,"context_line":""},{"line_number":1250,"context_line":"    @patch.object(DatabaseBroker, \u0027validate_metadata\u0027)"},{"line_number":1251,"context_line":"    def test_validate_metadata_is_called_from_update_metadata(self, mock):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_350b8724","line":1248,"in_reply_to":"5f7c97a3_5cfbe345","updated":"2018-05-11 20:26:45.000000000","message":"Proposed against master: https://review.openstack.org/567933","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1377,"context_line":""},{"line_number":1378,"context_line":"    def test_skip_commits(self):"},{"line_number":1379,"context_line":"        broker \u003d DatabaseBroker(\u0027:memory:\u0027)"},{"line_number":1380,"context_line":"        self.assertTrue(broker._skip_commit_puts())"},{"line_number":1381,"context_line":""},{"line_number":1382,"context_line":"        # not initialized"},{"line_number":1383,"context_line":"        db_file \u003d os.path.join(self.testdir, \u00271.db\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_e70b3821","line":1380,"updated":"2018-05-10 22:58:32.000000000","message":"Should we at least initialize the in-memory broker? Otherwise, this feels a lot like the not-initialized test below...","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1377,"context_line":""},{"line_number":1378,"context_line":"    def test_skip_commits(self):"},{"line_number":1379,"context_line":"        broker \u003d DatabaseBroker(\u0027:memory:\u0027)"},{"line_number":1380,"context_line":"        self.assertTrue(broker._skip_commit_puts())"},{"line_number":1381,"context_line":""},{"line_number":1382,"context_line":"        # not initialized"},{"line_number":1383,"context_line":"        db_file \u003d os.path.join(self.testdir, \u00271.db\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_6b1feab6","line":1380,"in_reply_to":"5f7c97a3_e70b3821","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1391,"context_line":"        self.assertTrue(broker._skip_commit_puts())"},{"line_number":1392,"context_line":""},{"line_number":1393,"context_line":"        # pending file exists"},{"line_number":1394,"context_line":"        self.assertFalse(os.path.exists(broker.pending_file))  # sanity check"},{"line_number":1395,"context_line":"        with open(broker.pending_file, \u0027wb\u0027):"},{"line_number":1396,"context_line":"            pass"},{"line_number":1397,"context_line":"        self.assertFalse(broker._skip_commit_puts())"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_dc11335f","line":1394,"updated":"2018-05-10 22:58:32.000000000","message":"The order of our sanity checks seems a little odd... Like, it wasn\u0027t immediately obvious to me that the constructor *doesn\u0027t* pop the db into existence until I read the sanity check after the call to initialize later... and this sanity check really belongs *before* our assertion on line 1391. How about\n\n diff --git a/test/unit/common/test_db.py b/test/unit/common/test_db.py\n index 4decf05ca..165304762 100644\n --- a/test/unit/common/test_db.py\n +++ b/test/unit/common/test_db.py\n @@ -1382,18 +1382,20 @@ class TestDatabaseBroker(unittest.TestCase):\n          # not initialized\n          db_file \u003d os.path.join(self.testdir, \u00271.db\u0027)\n          broker \u003d DatabaseBroker(db_file)\n +        self.assertFalse(os.path.exists(broker.db_file))  # sanity check\n          self.assertTrue(broker._skip_commit_puts())\n  \n          # no pending file\n          broker._initialize \u003d MagicMock()\n          broker.initialize(Timestamp.now())\n          self.assertTrue(os.path.exists(broker.db_file))  # sanity check\n +        self.assertFalse(os.path.exists(broker.pending_file))  # sanity check\n          self.assertTrue(broker._skip_commit_puts())\n  \n          # pending file exists\n -        self.assertFalse(os.path.exists(broker.pending_file))  # sanity check\n          with open(broker.pending_file, \u0027wb\u0027):\n              pass\n +        self.assertTrue(os.path.exists(broker.pending_file))  # sanity check\n          self.assertFalse(broker._skip_commit_puts())\n  \n          # do_commits is False\n\n(though that last one may be excessive)","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1391,"context_line":"        self.assertTrue(broker._skip_commit_puts())"},{"line_number":1392,"context_line":""},{"line_number":1393,"context_line":"        # pending file exists"},{"line_number":1394,"context_line":"        self.assertFalse(os.path.exists(broker.pending_file))  # sanity check"},{"line_number":1395,"context_line":"        with open(broker.pending_file, \u0027wb\u0027):"},{"line_number":1396,"context_line":"            pass"},{"line_number":1397,"context_line":"        self.assertFalse(broker._skip_commit_puts())"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_2b7b32f5","line":1394,"in_reply_to":"5f7c97a3_dc11335f","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1396,"context_line":"            pass"},{"line_number":1397,"context_line":"        self.assertFalse(broker._skip_commit_puts())"},{"line_number":1398,"context_line":""},{"line_number":1399,"context_line":"        # do_commits is False"},{"line_number":1400,"context_line":"        broker.skip_commits \u003d True"},{"line_number":1401,"context_line":"        self.assertTrue(broker._skip_commit_puts())"},{"line_number":1402,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_c71f1c59","line":1399,"range":{"start_line":1399,"start_character":10,"end_line":1399,"end_character":29},"updated":"2018-05-10 22:58:32.000000000","message":"skip_commits is True","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1396,"context_line":"            pass"},{"line_number":1397,"context_line":"        self.assertFalse(broker._skip_commit_puts())"},{"line_number":1398,"context_line":""},{"line_number":1399,"context_line":"        # do_commits is False"},{"line_number":1400,"context_line":"        broker.skip_commits \u003d True"},{"line_number":1401,"context_line":"        self.assertTrue(broker._skip_commit_puts())"},{"line_number":1402,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_4b80eec0","line":1399,"range":{"start_line":1399,"start_character":10,"end_line":1399,"end_character":29},"in_reply_to":"5f7c97a3_c71f1c59","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1398,"context_line":""},{"line_number":1399,"context_line":"        # do_commits is False"},{"line_number":1400,"context_line":"        broker.skip_commits \u003d True"},{"line_number":1401,"context_line":"        self.assertTrue(broker._skip_commit_puts())"},{"line_number":1402,"context_line":""},{"line_number":1403,"context_line":"    def test_commit_puts(self):"},{"line_number":1404,"context_line":"        db_file \u003d os.path.join(self.testdir, \u00271.db\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_873da4c5","line":1401,"updated":"2018-05-10 22:58:32.000000000","message":"Do we ever check the plumbing on the constructor? How about\n\n diff --git a/test/unit/common/test_db.py b/test/unit/common/test_db.py\n index 4decf05ca..d01e37a49 100644\n --- a/test/unit/common/test_db.py\n +++ b/test/unit/common/test_db.py\n @@ -1396,10 +1396,18 @@ class TestDatabaseBroker(unittest.TestCase):\n              pass\n          self.assertFalse(broker._skip_commit_puts())\n  \n -        # do_commits is False\n +        # skip_commits is True\n          broker.skip_commits \u003d True\n          self.assertTrue(broker._skip_commit_puts())\n  \n +        # re-init\n +        broker \u003d DatabaseBroker(db_file)\n +        self.assertFalse(broker._skip_commit_puts())\n +\n +        # constructor can override\n +        broker \u003d DatabaseBroker(db_file, skip_commits\u003dTrue)\n +        self.assertTrue(broker._skip_commit_puts())\n +\n      def test_commit_puts(self):\n          db_file \u003d os.path.join(self.testdir, \u00271.db\u0027)\n          broker \u003d DatabaseBroker(db_file)","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1398,"context_line":""},{"line_number":1399,"context_line":"        # do_commits is False"},{"line_number":1400,"context_line":"        broker.skip_commits \u003d True"},{"line_number":1401,"context_line":"        self.assertTrue(broker._skip_commit_puts())"},{"line_number":1402,"context_line":""},{"line_number":1403,"context_line":"    def test_commit_puts(self):"},{"line_number":1404,"context_line":"        db_file \u003d os.path.join(self.testdir, \u00271.db\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_2b649249","line":1401,"in_reply_to":"5f7c97a3_873da4c5","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1410,"context_line":""},{"line_number":1411,"context_line":"        # merge given list"},{"line_number":1412,"context_line":"        mock_merge_items \u003d MagicMock()"},{"line_number":1413,"context_line":"        broker.merge_items \u003d mock_merge_items"},{"line_number":1414,"context_line":"        items \u003d [\u0027test\u0027]"},{"line_number":1415,"context_line":"        broker._commit_puts(items)"},{"line_number":1416,"context_line":"        mock_merge_items.assert_called_once_with(items)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_a7c46092","line":1413,"updated":"2018-05-10 22:58:32.000000000","message":"Better to patch? Though it\u0027d require that we stub out merge_items in common/db.py ... *shrug*\n\n diff --git a/swift/common/db.py b/swift/common/db.py\n index 62a23dbf6..d8b597aeb 100644\n --- a/swift/common/db.py\n +++ b/swift/common/db.py\n @@ -731,6 +731,12 @@ class DatabaseBroker(object):\n          \"\"\"\n          raise NotImplementedError\n  \n +    def merge_items(self, item_list, source\u003dNone):\n +        \"\"\"\n +        Save :param:item_list to the database.\n +        \"\"\"\n +        raise NotImplementedError\n +\n      def make_tuple_for_pickle(self, record):\n          \"\"\"\n          Turn this db record dict into the format this service uses for\n diff --git a/test/unit/common/test_db.py b/test/unit/common/test_db.py\n index 4decf05ca..edf50df50 100644\n --- a/test/unit/common/test_db.py\n +++ b/test/unit/common/test_db.py\n @@ -1409,29 +1409,25 @@ class TestDatabaseBroker(unittest.TestCase):\n              pass\n  \n          # merge given list\n -        mock_merge_items \u003d MagicMock()\n -        broker.merge_items \u003d mock_merge_items\n -        items \u003d [\u0027test\u0027]\n -        broker._commit_puts(items)\n -        mock_merge_items.assert_called_once_with(items)\n +        with patch.object(broker, \u0027merge_items\u0027) as mock_merge_items:\n +            broker._commit_puts([\u0027test\u0027])\n +        mock_merge_items.assert_called_once_with([\u0027test\u0027])\n  \n          # load file and merge\n          with open(broker.pending_file, \u0027wb\u0027) as fd:\n              fd.write(\u0027:1:2:99\u0027)\n -        mock_merge_items \u003d MagicMock()\n -        broker.merge_items \u003d mock_merge_items\n -        broker._commit_puts_load \u003d lambda l, e: l.append(e)\n -        broker._commit_puts()\n +        with patch.object(broker, \u0027merge_items\u0027) as mock_merge_items:\n +            broker._commit_puts_load \u003d lambda l, e: l.append(e)\n +            broker._commit_puts()\n          mock_merge_items.assert_called_once_with([\u00271\u0027, \u00272\u0027, \u002799\u0027])\n          self.assertEqual(0, os.path.getsize(broker.pending_file))\n  \n          # load file and merge with given list\n          with open(broker.pending_file, \u0027wb\u0027) as fd:\n              fd.write(\u0027:bad\u0027)\n -        mock_merge_items \u003d MagicMock()\n -        broker.merge_items \u003d mock_merge_items\n -        broker._commit_puts_load \u003d lambda l, e: l.append(e)\n -        broker._commit_puts([\u0027not\u0027])\n +        with patch.object(broker, \u0027merge_items\u0027) as mock_merge_items:\n +            broker._commit_puts_load \u003d lambda l, e: l.append(e)\n +            broker._commit_puts([\u0027not\u0027])\n          mock_merge_items.assert_called_once_with([\u0027not\u0027, \u0027bad\u0027])\n          self.assertEqual(0, os.path.getsize(broker.pending_file))\n  \n @@ -1442,10 +1438,9 @@ class TestDatabaseBroker(unittest.TestCase):\n          broker.initialize(Timestamp.now())\n          with open(broker.pending_file, \u0027wb\u0027) as fd:\n              fd.write(\u0027:ignored\u0027)\n -        mock_merge_items \u003d MagicMock()\n -        broker.merge_items \u003d mock_merge_items\n -        broker._commit_puts_load \u003d lambda l, e: l.append(e)\n -        broker._commit_puts([\u0027hmmm\u0027])\n +        with patch.object(broker, \u0027merge_items\u0027) as mock_merge_items:\n +            broker._commit_puts_load \u003d lambda l, e: l.append(e)\n +            broker._commit_puts([\u0027hmmm\u0027])\n          mock_merge_items.assert_not_called()\n          with open(broker.pending_file, \u0027rb\u0027) as fd:\n              self.assertEqual(\u0027:ignored\u0027, fd.read())","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1410,"context_line":""},{"line_number":1411,"context_line":"        # merge given list"},{"line_number":1412,"context_line":"        mock_merge_items \u003d MagicMock()"},{"line_number":1413,"context_line":"        broker.merge_items \u003d mock_merge_items"},{"line_number":1414,"context_line":"        items \u003d [\u0027test\u0027]"},{"line_number":1415,"context_line":"        broker._commit_puts(items)"},{"line_number":1416,"context_line":"        mock_merge_items.assert_called_once_with(items)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_6b05aa13","line":1413,"in_reply_to":"5f7c97a3_a7c46092","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1437,"context_line":""},{"line_number":1438,"context_line":"        # skip_commits True - no merge"},{"line_number":1439,"context_line":"        db_file \u003d os.path.join(self.testdir, \u00272.db\u0027)"},{"line_number":1440,"context_line":"        broker \u003d DatabaseBroker(db_file, skip_commits\u003dTrue)"},{"line_number":1441,"context_line":"        broker._initialize \u003d MagicMock()"},{"line_number":1442,"context_line":"        broker.initialize(Timestamp.now())"},{"line_number":1443,"context_line":"        with open(broker.pending_file, \u0027wb\u0027) as fd:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_0778b48d","line":1440,"range":{"start_line":1440,"start_character":41,"end_line":1440,"end_character":58},"updated":"2018-05-10 22:58:32.000000000","message":"Ah, this is where we test the constructor plumbing...","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1437,"context_line":""},{"line_number":1438,"context_line":"        # skip_commits True - no merge"},{"line_number":1439,"context_line":"        db_file \u003d os.path.join(self.testdir, \u00272.db\u0027)"},{"line_number":1440,"context_line":"        broker \u003d DatabaseBroker(db_file, skip_commits\u003dTrue)"},{"line_number":1441,"context_line":"        broker._initialize \u003d MagicMock()"},{"line_number":1442,"context_line":"        broker.initialize(Timestamp.now())"},{"line_number":1443,"context_line":"        with open(broker.pending_file, \u0027wb\u0027) as fd:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_c60cf542","line":1440,"range":{"start_line":1440,"start_character":41,"end_line":1440,"end_character":58},"in_reply_to":"5f7c97a3_0778b48d","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1448,"context_line":"        broker._commit_puts([\u0027hmmm\u0027])"},{"line_number":1449,"context_line":"        mock_merge_items.assert_not_called()"},{"line_number":1450,"context_line":"        with open(broker.pending_file, \u0027rb\u0027) as fd:"},{"line_number":1451,"context_line":"            self.assertEqual(\u0027:ignored\u0027, fd.read())"},{"line_number":1452,"context_line":""},{"line_number":1453,"context_line":"    def test_put_record(self):"},{"line_number":1454,"context_line":"        db_file \u003d os.path.join(self.testdir, \u00271.db\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_e7dfb837","line":1451,"updated":"2018-05-10 22:58:32.000000000","message":"This makes me a little nervous -- \u0027hmm\u0027 just *disappears*? Seems like an argument in favor of keeping\n\n if self.skip_commits:\n     raise DatabaseConnectionError(self.db_file, \"commits not accepted\")\n\naround somewhere... or maybe we ought to be exercising put_record more?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1448,"context_line":"        broker._commit_puts([\u0027hmmm\u0027])"},{"line_number":1449,"context_line":"        mock_merge_items.assert_not_called()"},{"line_number":1450,"context_line":"        with open(broker.pending_file, \u0027rb\u0027) as fd:"},{"line_number":1451,"context_line":"            self.assertEqual(\u0027:ignored\u0027, fd.read())"},{"line_number":1452,"context_line":""},{"line_number":1453,"context_line":"    def test_put_record(self):"},{"line_number":1454,"context_line":"        db_file \u003d os.path.join(self.testdir, \u00271.db\u0027)"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_e611f15e","line":1451,"in_reply_to":"5f7c97a3_e7dfb837","updated":"2018-05-11 14:26:48.000000000","message":"agree, I overlooked the item_list arg route when removing the check on skip_commits in put_record. Will put that back AND add a check in _commit_puts in case that ever gets called with an item list from another place.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1484,"context_line":"                fd.write(\u0027x\u0027 * 100000)"},{"line_number":1485,"context_line":"        with patch.object(broker, \u0027_commit_puts\u0027) as mock_commit_puts:"},{"line_number":1486,"context_line":"            broker.put_record(\u0027direct\u0027)"},{"line_number":1487,"context_line":"        mock_commit_puts.called_once_with([\u0027direct\u0027])"},{"line_number":1488,"context_line":""},{"line_number":1489,"context_line":""},{"line_number":1490,"context_line":"if __name__ \u003d\u003d \u0027__main__\u0027:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_a73d402c","line":1487,"updated":"2018-05-10 22:58:32.000000000","message":"Yeah, this case -- I really worry about what happens when we get *here* with skip_commits\u003dTrue!","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1484,"context_line":"                fd.write(\u0027x\u0027 * 100000)"},{"line_number":1485,"context_line":"        with patch.object(broker, \u0027_commit_puts\u0027) as mock_commit_puts:"},{"line_number":1486,"context_line":"            broker.put_record(\u0027direct\u0027)"},{"line_number":1487,"context_line":"        mock_commit_puts.called_once_with([\u0027direct\u0027])"},{"line_number":1488,"context_line":""},{"line_number":1489,"context_line":""},{"line_number":1490,"context_line":"if __name__ \u003d\u003d \u0027__main__\u0027:"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_a62699cd","line":1487,"in_reply_to":"5f7c97a3_a73d402c","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d57fac29389a2cdae651fa42ba581775a7a6ac64","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        return (zero_like(info[\u0027count\u0027]) and"},{"line_number":319,"context_line":"                (Timestamp(now - reclaim_age) \u003e"},{"line_number":320,"context_line":"                 Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":321,"context_line":"                 Timestamp(info[\u0027put_timestamp\u0027])))"},{"line_number":322,"context_line":""},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"class TestExampleBroker(unittest.TestCase):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_32107da8","line":321,"updated":"2018-05-11 19:48:44.000000000","message":"ExampleBroker *does* inherit from DatabaseBroker, so I don\u0027t think this is necessary now.","commit_id":"2b463dbf21699380386d7c5fcaa8f728b2ab092a"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"3ce8a55dc7a8d5ab7ac6b0af175cab5a73b3df34","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        return (zero_like(info[\u0027count\u0027]) and"},{"line_number":319,"context_line":"                (Timestamp(now - reclaim_age) \u003e"},{"line_number":320,"context_line":"                 Timestamp(info[\u0027delete_timestamp\u0027]) \u003e"},{"line_number":321,"context_line":"                 Timestamp(info[\u0027put_timestamp\u0027])))"},{"line_number":322,"context_line":""},{"line_number":323,"context_line":""},{"line_number":324,"context_line":"class TestExampleBroker(unittest.TestCase):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_666153a9","line":321,"in_reply_to":"5f7c97a3_32107da8","updated":"2018-05-12 00:25:30.000000000","message":"Yeah, but implementation is different from that in either... I removed it and this happened:\n\nFAIL: test_clean_up_after_deleted_brokers (test.unit.common.test_db_replicator.TestReplicatorSync)\n----------------------------------------------------------------------\nTraceback (most recent call last):\n  File \"/q/zaitcev/hail/swift-deep-review/test/unit/common/test_db_replicator.py\", line 2209, in test_clean_up_after_deleted_brokers\n    self.assertEqual(1, daemon.stats[\u0027remove\u0027])\nAssertionError: 1 !\u003d 0","commit_id":"2b463dbf21699380386d7c5fcaa8f728b2ab092a"}],"test/unit/common/test_db_replicator.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":768,"context_line":"                res \u003d replicator._replicate_object(\u00270\u0027, db_path, \u0027node_id\u0027)"},{"line_number":769,"context_line":"        self.assertRaises(StopIteration, next, fake_replicate.side_effect)"},{"line_number":770,"context_line":"        self.assertEqual((True, [True, True, True]), res)"},{"line_number":771,"context_line":"        self.assertEqual(1, mock_delete.call_count)"},{"line_number":772,"context_line":"        self.assertFalse(replicator.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":773,"context_line":"        self.assertFalse(replicator.logger.get_lines_for_level(\u0027warning\u0027))"},{"line_number":774,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_ce0667cf","line":771,"range":{"start_line":771,"start_character":0,"end_line":771,"end_character":51},"updated":"2018-05-10 07:50:41.000000000","message":"This looks weird to me because this method tests the replicate_object call on PRIMARY node so the response should be called twice, shouldbehere \u003d True, then no delete_db calls even when all responses are successful.\n\nThe case that is testing not_shouldbehere is from Line 811, isn\u0027t it?","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84af3b7a5f814809ad669de45a5217dd65ea3925","unresolved":false,"context_lines":[{"line_number":768,"context_line":"                res \u003d replicator._replicate_object(\u00270\u0027, db_path, \u0027node_id\u0027)"},{"line_number":769,"context_line":"        self.assertRaises(StopIteration, next, fake_replicate.side_effect)"},{"line_number":770,"context_line":"        self.assertEqual((True, [True, True, True]), res)"},{"line_number":771,"context_line":"        self.assertEqual(1, mock_delete.call_count)"},{"line_number":772,"context_line":"        self.assertFalse(replicator.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":773,"context_line":"        self.assertFalse(replicator.logger.get_lines_for_level(\u0027warning\u0027))"},{"line_number":774,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_3a687585","line":771,"range":{"start_line":771,"start_character":0,"end_line":771,"end_character":51},"in_reply_to":"5f7c97a3_ce0667cf","updated":"2018-05-10 11:20:52.000000000","message":"using \u0027node_id\u0027 in the call to replicate_object makes it appear to be a handoff. I\u0027ll add a comment to make that clear. \n\nThe primary node case is tested at line 857","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":861,"context_line":"                               return_value\u003dTrue) as mock_cleanup:"},{"line_number":862,"context_line":"            replicator._replicate_object(\u00270\u0027, \u0027/path/to/file\u0027, primary_node_id)"},{"line_number":863,"context_line":"        mock_cleanup.assert_not_called()"},{"line_number":864,"context_line":"        self.assertFalse(self.delete_db_calls)"},{"line_number":865,"context_line":"        self.assertEqual(0, replicator.stats[\u0027failure\u0027])"},{"line_number":866,"context_line":"        self.assertEqual(2, replicator.stats[\u0027success\u0027])"},{"line_number":867,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_4ee817e1","line":864,"updated":"2018-05-10 07:50:41.000000000","message":"Hmm... the primary case I said above exists here.","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":896,"context_line":"                broker, info, [True] * 3)"},{"line_number":897,"context_line":"        mock_delete_db.assert_not_called()"},{"line_number":898,"context_line":"        self.assertTrue(res)"},{"line_number":899,"context_line":"        broker.stub_replication_info \u003d None"},{"line_number":900,"context_line":"        self.assertEqual([\u0027Not deleting db %s (2 new rows)\u0027 % broker.db_file],"},{"line_number":901,"context_line":"                         replicator.logger.get_lines_for_level(\u0027debug\u0027))"},{"line_number":902,"context_line":"        replicator.logger.clear()"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_ce90a746","line":899,"updated":"2018-05-10 07:50:41.000000000","message":"Unnecessary None assignment? Because it is overwritten at L904","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84af3b7a5f814809ad669de45a5217dd65ea3925","unresolved":false,"context_lines":[{"line_number":896,"context_line":"                broker, info, [True] * 3)"},{"line_number":897,"context_line":"        mock_delete_db.assert_not_called()"},{"line_number":898,"context_line":"        self.assertTrue(res)"},{"line_number":899,"context_line":"        broker.stub_replication_info \u003d None"},{"line_number":900,"context_line":"        self.assertEqual([\u0027Not deleting db %s (2 new rows)\u0027 % broker.db_file],"},{"line_number":901,"context_line":"                         replicator.logger.get_lines_for_level(\u0027debug\u0027))"},{"line_number":902,"context_line":"        replicator.logger.clear()"}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_5afa11bd","line":899,"in_reply_to":"5f7c97a3_ce90a746","updated":"2018-05-10 11:20:52.000000000","message":"Done","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"a7a222f188b167ea5e783651e62c0f2a93d1e1b3","unresolved":false,"context_lines":[{"line_number":1260,"context_line":"            self.assertEqual(\u0027204 No Content\u0027, response.status)"},{"line_number":1261,"context_line":"            self.assertEqual(204, response.status_int)"},{"line_number":1262,"context_line":""},{"line_number":1263,"context_line":"    def test_complete_rsync_db_exists(self):"},{"line_number":1264,"context_line":"        rpc \u003d db_replicator.ReplicatorRpc(\u0027/\u0027, \u0027/\u0027, FakeBroker,"},{"line_number":1265,"context_line":"                                          mount_check\u003dFalse)"},{"line_number":1266,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_ae020b6e","line":1263,"range":{"start_line":1263,"start_character":31,"end_line":1263,"end_character":38},"updated":"2018-05-10 07:50:41.000000000","message":"it looks like no state change and the response is 404 Not Found but... db_exists?","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"84af3b7a5f814809ad669de45a5217dd65ea3925","unresolved":false,"context_lines":[{"line_number":1260,"context_line":"            self.assertEqual(\u0027204 No Content\u0027, response.status)"},{"line_number":1261,"context_line":"            self.assertEqual(204, response.status_int)"},{"line_number":1262,"context_line":""},{"line_number":1263,"context_line":"    def test_complete_rsync_db_exists(self):"},{"line_number":1264,"context_line":"        rpc \u003d db_replicator.ReplicatorRpc(\u0027/\u0027, \u0027/\u0027, FakeBroker,"},{"line_number":1265,"context_line":"                                          mount_check\u003dFalse)"},{"line_number":1266,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"5f7c97a3_badfa538","line":1263,"range":{"start_line":1263,"start_character":31,"end_line":1263,"end_character":38},"in_reply_to":"5f7c97a3_ae020b6e","updated":"2018-05-10 11:20:52.000000000","message":"yes, if the db exists on remote node (i.e. complete rsync should not be used) then a 404 is returned (a bit weird that it\u0027s not a 409 or other status).\n\nhttps://github.com/openstack/swift/blob/master/swift/common/db_replicator.py#L866","commit_id":"8672aa4c7c9a956fe027f6c4ec984fd7ca701b50"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":191,"context_line":"        return self.mtime"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":""},{"line_number":194,"context_line":"class FakeBroker(object):"},{"line_number":195,"context_line":"    db_file \u003d __file__"},{"line_number":196,"context_line":"    get_repl_missing_table \u003d False"},{"line_number":197,"context_line":"    stub_replication_info \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_47fb0c46","line":194,"updated":"2018-05-10 22:58:32.000000000","message":"Should we have this subclass DatabaseBroker? I worry about us changing the definition for is_reclaimable (say) somewhere under swift then only remembering to update it in one of the two test files...\n\nI\u0027ve got this feeling like a lot of what this defines could go away if we use our classes.","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":191,"context_line":"        return self.mtime"},{"line_number":192,"context_line":""},{"line_number":193,"context_line":""},{"line_number":194,"context_line":"class FakeBroker(object):"},{"line_number":195,"context_line":"    db_file \u003d __file__"},{"line_number":196,"context_line":"    get_repl_missing_table \u003d False"},{"line_number":197,"context_line":"    stub_replication_info \u003d None"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_351635aa","line":194,"in_reply_to":"5f7c97a3_47fb0c46","updated":"2018-05-11 14:26:48.000000000","message":"Maybe, but I\u0027d like to avoid taking that on here - follow up on master perhaps?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":247,"context_line":"            info.update(self.stub_replication_info)"},{"line_number":248,"context_line":"        return info"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":"    def get_max_row(self):"},{"line_number":251,"context_line":"        return self.get_replication_info()[\u0027max_row\u0027]"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    def is_reclaimable(self, now, reclaim_age):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_67f88848","line":250,"updated":"2018-05-10 22:58:32.000000000","message":"No table arg?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":247,"context_line":"            info.update(self.stub_replication_info)"},{"line_number":248,"context_line":"        return info"},{"line_number":249,"context_line":""},{"line_number":250,"context_line":"    def get_max_row(self):"},{"line_number":251,"context_line":"        return self.get_replication_info()[\u0027max_row\u0027]"},{"line_number":252,"context_line":""},{"line_number":253,"context_line":"    def is_reclaimable(self, now, reclaim_age):"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_155f7972","line":250,"in_reply_to":"5f7c97a3_67f88848","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":721,"context_line":"        self.assertEqual(0, mock_delete.call_count)"},{"line_number":722,"context_line":"        lines \u003d replicator.logger.get_lines_for_level(\u0027error\u0027)"},{"line_number":723,"context_line":"        self.assertIn(\u0027ERROR syncing\u0027, lines[0])"},{"line_number":724,"context_line":"        self.assertIn(\u0027ERROR syncing\u0027, lines[1])"},{"line_number":725,"context_line":"        self.assertFalse(replicator.logger.get_lines_for_level(\u0027warning\u0027))"},{"line_number":726,"context_line":"        replicator.logger.clear()"},{"line_number":727,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_421a1a6f","line":724,"updated":"2018-05-10 22:58:32.000000000","message":"Assert length?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":721,"context_line":"        self.assertEqual(0, mock_delete.call_count)"},{"line_number":722,"context_line":"        lines \u003d replicator.logger.get_lines_for_level(\u0027error\u0027)"},{"line_number":723,"context_line":"        self.assertIn(\u0027ERROR syncing\u0027, lines[0])"},{"line_number":724,"context_line":"        self.assertIn(\u0027ERROR syncing\u0027, lines[1])"},{"line_number":725,"context_line":"        self.assertFalse(replicator.logger.get_lines_for_level(\u0027warning\u0027))"},{"line_number":726,"context_line":"        replicator.logger.clear()"},{"line_number":727,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_55f73160","line":724,"in_reply_to":"5f7c97a3_421a1a6f","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":772,"context_line":"        self.assertEqual((True, [True, True, True]), res)"},{"line_number":773,"context_line":"        self.assertEqual(1, mock_delete.call_count)"},{"line_number":774,"context_line":"        self.assertFalse(replicator.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":775,"context_line":"        self.assertFalse(replicator.logger.get_lines_for_level(\u0027warning\u0027))"},{"line_number":776,"context_line":""},{"line_number":777,"context_line":"    def test_replicate_object_quarantine(self):"},{"line_number":778,"context_line":"        replicator \u003d TestReplicator({})"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_2206fe1e","line":775,"updated":"2018-05-10 22:58:32.000000000","message":"+1000, WAY better.\n\nWhich path did the old test take? It never patched out swift.common.db_replicator.ReplConnection.replicate so... IDK.. probably three exceptions were raised?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":772,"context_line":"        self.assertEqual((True, [True, True, True]), res)"},{"line_number":773,"context_line":"        self.assertEqual(1, mock_delete.call_count)"},{"line_number":774,"context_line":"        self.assertFalse(replicator.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":775,"context_line":"        self.assertFalse(replicator.logger.get_lines_for_level(\u0027warning\u0027))"},{"line_number":776,"context_line":""},{"line_number":777,"context_line":"    def test_replicate_object_quarantine(self):"},{"line_number":778,"context_line":"        replicator \u003d TestReplicator({})"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_d5f8217c","line":775,"in_reply_to":"5f7c97a3_2206fe1e","updated":"2018-05-11 14:26:48.000000000","message":"IIRC the old test verified that if a bunch of KeyErrors were raised due to inadequate test setup then they got swallowed inside replicate_object :/","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":822,"context_line":"            replicator._replicate_object(\u00270\u0027, \u0027/path/to/file\u0027, \u0027node_id\u0027)"},{"line_number":823,"context_line":"        mock_cleanup.assert_called_once_with(mock.ANY, mock.ANY, [True] * 3)"},{"line_number":824,"context_line":"        self.assertIsInstance(mock_cleanup.call_args[0][0],"},{"line_number":825,"context_line":"                              replicator.brokerclass)"},{"line_number":826,"context_line":"        self.assertEqual([\u0027/path/to/file\u0027], self.delete_db_calls)"},{"line_number":827,"context_line":"        self.assertEqual(0, replicator.stats[\u0027failure\u0027])"},{"line_number":828,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_029d02bb","line":825,"range":{"start_line":825,"start_character":41,"end_line":825,"end_character":52},"updated":"2018-05-10 22:58:32.000000000","message":"Oh... I guess I\u0027m starting to see why we have a de novo FakeBroker ... :-/","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":822,"context_line":"            replicator._replicate_object(\u00270\u0027, \u0027/path/to/file\u0027, \u0027node_id\u0027)"},{"line_number":823,"context_line":"        mock_cleanup.assert_called_once_with(mock.ANY, mock.ANY, [True] * 3)"},{"line_number":824,"context_line":"        self.assertIsInstance(mock_cleanup.call_args[0][0],"},{"line_number":825,"context_line":"                              replicator.brokerclass)"},{"line_number":826,"context_line":"        self.assertEqual([\u0027/path/to/file\u0027], self.delete_db_calls)"},{"line_number":827,"context_line":"        self.assertEqual(0, replicator.stats[\u0027failure\u0027])"},{"line_number":828,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_354e3597","line":825,"range":{"start_line":825,"start_character":41,"end_line":825,"end_character":52},"in_reply_to":"5f7c97a3_029d02bb","updated":"2018-05-11 14:26:48.000000000","message":"Done","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":1273,"context_line":"                                          [\u0027arg1\u0027, \u0027arg2\u0027])"},{"line_number":1274,"context_line":"            mock_os.path.exists.assert_called_with(\u0027/data/db.db\u0027)"},{"line_number":1275,"context_line":"            self.assertEqual(\u0027404 Not Found\u0027, response.status)"},{"line_number":1276,"context_line":"            self.assertEqual(404, response.status_int)"},{"line_number":1277,"context_line":""},{"line_number":1278,"context_line":"    def test_complete_rsync_old_file_does_not_exist(self):"},{"line_number":1279,"context_line":"        rpc \u003d db_replicator.ReplicatorRpc(\u0027/\u0027, \u0027/\u0027, FakeBroker,"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_02d42247","line":1276,"updated":"2018-05-10 22:58:32.000000000","message":"Wait, what? So the db exists... but we 404? Why?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":1273,"context_line":"                                          [\u0027arg1\u0027, \u0027arg2\u0027])"},{"line_number":1274,"context_line":"            mock_os.path.exists.assert_called_with(\u0027/data/db.db\u0027)"},{"line_number":1275,"context_line":"            self.assertEqual(\u0027404 Not Found\u0027, response.status)"},{"line_number":1276,"context_line":"            self.assertEqual(404, response.status_int)"},{"line_number":1277,"context_line":""},{"line_number":1278,"context_line":"    def test_complete_rsync_old_file_does_not_exist(self):"},{"line_number":1279,"context_line":"        rpc \u003d db_replicator.ReplicatorRpc(\u0027/\u0027, \u0027/\u0027, FakeBroker,"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_d587c1b4","line":1276,"in_reply_to":"5f7c97a3_02d42247","updated":"2018-05-11 14:26:48.000000000","message":"I know, it\u0027s an odd choice of status, but it\u0027s always been that way. \n\nhttps://github.com/openstack/swift/commit/001407b969bc12d48bd7f10960f84f519bb19111#diff-8f044c17d657bf0a3b58770284721d5fR503","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7fa52b83bb951cf88ada9cae2db1e543f4bf7d60","unresolved":false,"context_lines":[{"line_number":2114,"context_line":"            conf.update(conf_updates)"},{"line_number":2115,"context_line":"        return self.replicator_daemon(conf, logger\u003dself.logger)"},{"line_number":2116,"context_line":""},{"line_number":2117,"context_line":"    def _install_fake_rsync_file(self, daemon, captured_calls\u003dNone):"},{"line_number":2118,"context_line":"        def _rsync_file(db_file, remote_file, **kwargs):"},{"line_number":2119,"context_line":"            if captured_calls is not None:"},{"line_number":2120,"context_line":"                captured_calls.append((db_file, remote_file, kwargs))"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_a249ae31","line":2117,"range":{"start_line":2117,"start_character":47,"end_line":2117,"end_character":66},"updated":"2018-05-10 22:58:32.000000000","message":"Eh?","commit_id":"1815146a149a51ec759399986846f1962363b0e8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"20e5bd738f5fdfe61235026f30f216a93dbb4958","unresolved":false,"context_lines":[{"line_number":2114,"context_line":"            conf.update(conf_updates)"},{"line_number":2115,"context_line":"        return self.replicator_daemon(conf, logger\u003dself.logger)"},{"line_number":2116,"context_line":""},{"line_number":2117,"context_line":"    def _install_fake_rsync_file(self, daemon, captured_calls\u003dNone):"},{"line_number":2118,"context_line":"        def _rsync_file(db_file, remote_file, **kwargs):"},{"line_number":2119,"context_line":"            if captured_calls is not None:"},{"line_number":2120,"context_line":"                captured_calls.append((db_file, remote_file, kwargs))"}],"source_content_type":"text/x-python","patch_set":4,"id":"5f7c97a3_35339516","line":2117,"range":{"start_line":2117,"start_character":47,"end_line":2117,"end_character":66},"in_reply_to":"5f7c97a3_a249ae31","updated":"2018-05-11 14:26:48.000000000","message":"used in later patch, https://review.openstack.org/#/c/565744/5/test/unit/container/test_replicator.py@1427","commit_id":"1815146a149a51ec759399986846f1962363b0e8"}],"test/unit/container/test_backend.py":[{"author":{"_account_id":4608,"name":"Kota Tsuyuzaki","email":"bloodeagle40234@gmail.com","username":"tsuyuzaki-kota"},"change_message_id":"cc2daabc56fbbaf74691938617e31e8d042afec3","unresolved":false,"context_lines":[{"line_number":54,"context_line":""},{"line_number":55,"context_line":"    @patch_policies"},{"line_number":56,"context_line":"    def test_storage_policy_property(self):"},{"line_number":57,"context_line":"        ts \u003d make_timestamp_iter()"},{"line_number":58,"context_line":"        for policy in POLICIES:"},{"line_number":59,"context_line":"            broker \u003d ContainerBroker(\u0027:memory:\u0027, account\u003d\u0027a\u0027,"},{"line_number":60,"context_line":"                                     container\u003d\u0027policy_%s\u0027 % policy.name)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f7c97a3_e0358b47","line":57,"updated":"2018-05-09 11:33:49.000000000","message":"nice","commit_id":"bf338d3a965dfafbd175b7db53c69059d96ec6f0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d57fac29389a2cdae651fa42ba581775a7a6ac64","unresolved":false,"context_lines":[{"line_number":2102,"context_line":"        hsh \u003d hash_path(\u0027a\u0027, \u0027c\u0027)"},{"line_number":2103,"context_line":"        expected_path \u003d os.path.join("},{"line_number":2104,"context_line":"            tempdir, \u0027containers\u0027, \u00270\u0027, hsh[-3:], hsh, hsh + \u0027.db\u0027)"},{"line_number":2105,"context_line":"        self.assertEqual(expected_path, broker.db_file)"},{"line_number":2106,"context_line":""},{"line_number":2107,"context_line":"        ts \u003d Timestamp.now()"},{"line_number":2108,"context_line":"        broker \u003d ContainerBroker.create_broker(tempdir, 0, \u0027a\u0027, \u0027c1\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"5f7c97a3_d204a94c","line":2105,"updated":"2018-05-11 19:48:44.000000000","message":"Add a\n\n self.assertTrue(os.path.exists(broker.db_file))\n\n?","commit_id":"2b463dbf21699380386d7c5fcaa8f728b2ab092a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"7bec18ab81c8a049bce348b7b99b1df16fe43d0b","unresolved":false,"context_lines":[{"line_number":2102,"context_line":"        hsh \u003d hash_path(\u0027a\u0027, \u0027c\u0027)"},{"line_number":2103,"context_line":"        expected_path \u003d os.path.join("},{"line_number":2104,"context_line":"            tempdir, \u0027containers\u0027, \u00270\u0027, hsh[-3:], hsh, hsh + \u0027.db\u0027)"},{"line_number":2105,"context_line":"        self.assertEqual(expected_path, broker.db_file)"},{"line_number":2106,"context_line":""},{"line_number":2107,"context_line":"        ts \u003d Timestamp.now()"},{"line_number":2108,"context_line":"        broker \u003d ContainerBroker.create_broker(tempdir, 0, \u0027a\u0027, \u0027c1\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_56662dc3","line":2105,"updated":"2018-05-14 17:49:20.000000000","message":"Still not a bad idea to have an existence check here -- just checking broker.db_file makes create_broker seem like a thin wrapper for ContainerBroker.__init__, when one of the important features of it (in my opinion) is that it ensure the db file actually exists.","commit_id":"ef65cea10160fe8c57a3c7737c1c8c11bb931b5f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5951a6e114afca5dc9c695c4ff94426f5d23d060","unresolved":false,"context_lines":[{"line_number":2102,"context_line":"        hsh \u003d hash_path(\u0027a\u0027, \u0027c\u0027)"},{"line_number":2103,"context_line":"        expected_path \u003d os.path.join("},{"line_number":2104,"context_line":"            tempdir, \u0027containers\u0027, \u00270\u0027, hsh[-3:], hsh, hsh + \u0027.db\u0027)"},{"line_number":2105,"context_line":"        self.assertEqual(expected_path, broker.db_file)"},{"line_number":2106,"context_line":""},{"line_number":2107,"context_line":"        ts \u003d Timestamp.now()"},{"line_number":2108,"context_line":"        broker \u003d ContainerBroker.create_broker(tempdir, 0, \u0027a\u0027, \u0027c1\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"5f7c97a3_e7d213d1","line":2105,"in_reply_to":"5f7c97a3_56662dc3","updated":"2018-05-15 17:33:35.000000000","message":"Agree, absolutely. Sorry if I missed that from previous reviews.","commit_id":"ef65cea10160fe8c57a3c7737c1c8c11bb931b5f"}]}
