)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"156b093c4b2eb1df8fcbb9b005b7764cd8d26f56","unresolved":false,"context_lines":[{"line_number":6,"context_line":""},{"line_number":7,"context_line":"X-Delete-At-* headers for all object nodes."},{"line_number":8,"context_line":""},{"line_number":9,"context_line":"It can be the case that the number of object replicas (O) is larger"},{"line_number":10,"context_line":"than the number of container replicas (C) for a given storage policy"},{"line_number":11,"context_line":"(especially in case of EC). Before this commit, only C object servers"},{"line_number":12,"context_line":"received the x-delete-at-* headers, which means that O - C object servers"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"df87a7cf_75c6344b","line":9,"range":{"start_line":9,"start_character":55,"end_line":9,"end_character":56},"updated":"2017-12-06 01:59:13.000000000","message":"nit: at first glance this could be confused with 0 (zero)","commit_id":"459f5efcd7cefaf65f898d27ab52d7ddaa65e2d0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"156b093c4b2eb1df8fcbb9b005b7764cd8d26f56","unresolved":false,"context_lines":[{"line_number":11,"context_line":"(especially in case of EC). Before this commit, only C object servers"},{"line_number":12,"context_line":"received the x-delete-at-* headers, which means that O - C object servers"},{"line_number":13,"context_line":"did not received the headers and produced a log warning. More important,"},{"line_number":14,"context_line":"a bug similar to bug #1460920 could have been created."},{"line_number":15,"context_line":""},{"line_number":16,"context_line":"It is now ensured that all O object servers receive the headers."},{"line_number":17,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"df87a7cf_f5b244e6","line":14,"range":{"start_line":14,"start_character":17,"end_line":14,"end_character":53},"updated":"2017-12-06 01:59:13.000000000","message":"I think that for the same bug to manifest, the object server expiring_objects_container_divisor would need to be misconfigured. As it is, every object server creates an async update for the delete at container, even the object servers that receive no headers. But, if the requests to the C object servers that *do* have headers are lost, and if the other object servers are misconfigured, then we might end up with no delete-at updates reaching the correct expirer container.","commit_id":"459f5efcd7cefaf65f898d27ab52d7ddaa65e2d0"}],"swift/obj/server.py":[{"author":{"_account_id":2622,"name":"Samuel Merritt","email":"spam+launchpad@andcheese.org","username":"torgomatic"},"change_message_id":"f143d6b95e280d8daef607b48b0868ef88f31c9d","unresolved":false,"context_lines":[{"line_number":392,"context_line":"            delete_at_container \u003d headers_in.get(\u0027X-Delete-At-Container\u0027, None)"},{"line_number":393,"context_line":"            if not delete_at_container:"},{"line_number":394,"context_line":"                # If header is missing, no update needed as sufficient other"},{"line_number":395,"context_line":"                # objers servers should perform the required update."},{"line_number":396,"context_line":"                return"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":"            partition \u003d headers_in.get(\u0027X-Delete-At-Partition\u0027, None)"}],"source_content_type":"text/x-python","patch_set":5,"id":"7f96bb07_bc700fa7","line":395,"range":{"start_line":395,"start_character":18,"end_line":395,"end_character":24},"updated":"2018-01-15 22:59:31.000000000","message":"*object","commit_id":"d7e55e1a70ac0f3cca709bff8167f2189c6ed26c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3c43143af6a033868bf0e7a9697ca79642351e55","unresolved":false,"context_lines":[{"line_number":396,"context_line":"                    \u0027expiring objects background %s to work properly. Making \u0027"},{"line_number":397,"context_line":"                    \u0027best guess as to the container name for now.\u0027 % op)"},{"line_number":398,"context_line":"                # TODO(gholt): In a future release, change the above warning to"},{"line_number":399,"context_line":"                # a raised exception and remove the guess code below."},{"line_number":400,"context_line":"                delete_at_container \u003d get_expirer_container("},{"line_number":401,"context_line":"                    delete_at, self.expiring_objects_container_divisor,"},{"line_number":402,"context_line":"                    account, container, obj)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_f953d469","side":"PARENT","line":399,"range":{"start_line":399,"start_character":41,"end_line":399,"end_character":68},"updated":"2018-01-17 01:45:06.000000000","message":"Do we know what this was referencing?","commit_id":"f994d99009b0166b4e10db47b326dd63d23b8d30"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"6375186ff392cc437350e94826cb2c0768111259","unresolved":false,"context_lines":[{"line_number":396,"context_line":"                    \u0027expiring objects background %s to work properly. Making \u0027"},{"line_number":397,"context_line":"                    \u0027best guess as to the container name for now.\u0027 % op)"},{"line_number":398,"context_line":"                # TODO(gholt): In a future release, change the above warning to"},{"line_number":399,"context_line":"                # a raised exception and remove the guess code below."},{"line_number":400,"context_line":"                delete_at_container \u003d get_expirer_container("},{"line_number":401,"context_line":"                    delete_at, self.expiring_objects_container_divisor,"},{"line_number":402,"context_line":"                    account, container, obj)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_2fba4a6d","side":"PARENT","line":399,"range":{"start_line":399,"start_character":41,"end_line":399,"end_character":68},"in_reply_to":"7f96bb07_f953d469","updated":"2018-01-17 04:10:43.000000000","message":"https://review.openstack.org/#/c/31584/ ???","commit_id":"f994d99009b0166b4e10db47b326dd63d23b8d30"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"64accd5696eff93d66dee220d2b28b31c7a4ffea","unresolved":false,"context_lines":[{"line_number":391,"context_line":"        if op !\u003d \u0027DELETE\u0027:"},{"line_number":392,"context_line":"            delete_at_container \u003d headers_in.get(\u0027X-Delete-At-Container\u0027, None)"},{"line_number":393,"context_line":"            if not delete_at_container:"},{"line_number":394,"context_line":"                # If header is missing, no update needed as sufficient other"},{"line_number":395,"context_line":"                # object servers should perform the required update."},{"line_number":396,"context_line":"                return"},{"line_number":397,"context_line":""},{"line_number":398,"context_line":"            partition \u003d headers_in.get(\u0027X-Delete-At-Partition\u0027, None)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_7a59e78b","line":395,"range":{"start_line":394,"start_character":18,"end_line":395,"end_character":68},"updated":"2018-01-17 13:04:19.000000000","message":"proxy servers older than 1.9.0 [1] don\u0027t send this header and there is no longer even an attempt to write items to the expiry container, nor an exception or warning to say \u0027upgrade your proxy!\u0027.\n\nMaking the condition any of the other x-delete-at-* headers (e.g. partition) would have avoided any backwards compatibility issue.\n\n[1] which is really old I know, I am \u0027just saying\u0027","commit_id":"a7c919e338c3f527fc8fc3a61fe25151ee4f6cf8"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"64accd5696eff93d66dee220d2b28b31c7a4ffea","unresolved":false,"context_lines":[{"line_number":402,"context_line":"                       zip((h.strip() for h in hosts.split(\u0027,\u0027)),"},{"line_number":403,"context_line":"                           (c.strip() for c in contdevices.split(\u0027,\u0027)))"},{"line_number":404,"context_line":"                       if all(upd) and partition]"},{"line_number":405,"context_line":"            if not updates:"},{"line_number":406,"context_line":"                updates \u003d [(None, None)]"},{"line_number":407,"context_line":"            headers_out[\u0027x-size\u0027] \u003d \u00270\u0027"},{"line_number":408,"context_line":"            headers_out[\u0027x-content-type\u0027] \u003d \u0027text/plain\u0027"},{"line_number":409,"context_line":"            headers_out[\u0027x-etag\u0027] \u003d \u0027d41d8cd98f00b204e9800998ecf8427e\u0027"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_d50b2cd3","line":406,"range":{"start_line":405,"start_character":12,"end_line":406,"end_character":40},"updated":"2018-01-17 13:04:19.000000000","message":"do we still need/want this? apart from in tests I am not sure when we now expect a request that has x-delete-at-container but not all of x-delete-at-{partition, host, device}","commit_id":"a7c919e338c3f527fc8fc3a61fe25151ee4f6cf8"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"156b093c4b2eb1df8fcbb9b005b7764cd8d26f56","unresolved":false,"context_lines":[{"line_number":302,"context_line":"        dan \u003d delete_at_nodes or []"},{"line_number":303,"context_line":"        dan_iter \u003d itertools.cycle(dan)"},{"line_number":304,"context_line":"        iter_len \u003d max(n_outgoing, len(dan))"},{"line_number":305,"context_line":"        for i, node in zip(xrange(iter_len), dan_iter):"},{"line_number":306,"context_line":"            i \u003d i % len(headers)"},{"line_number":307,"context_line":""},{"line_number":308,"context_line":"            headers[i][\u0027X-Delete-At-Container\u0027] \u003d delete_at_container"}],"source_content_type":"text/x-python","patch_set":2,"id":"df87a7cf_756e3496","line":305,"range":{"start_line":305,"start_character":27,"end_line":305,"end_character":33},"updated":"2017-12-06 01:59:13.000000000","message":"please use range for python 3 compatibility\n\nfor easier reading of the code, it might be nice to re-use the pattern at lines 294-297 i.e. end up with a loop described by:\n\n  while i \u003c n_updates_needed:\n      i +\u003d 1\n      \u003c set delete-at headers using next(dan_iter) \u003e","commit_id":"459f5efcd7cefaf65f898d27ab52d7ddaa65e2d0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3c43143af6a033868bf0e7a9697ca79642351e55","unresolved":false,"context_lines":[{"line_number":347,"context_line":"            set_container_update(index, next(container_iter))"},{"line_number":348,"context_line":"            if delete_at_nodes:"},{"line_number":349,"context_line":"                # We reverse the index in order to distribute the updates"},{"line_number":350,"context_line":"                # across all nodes."},{"line_number":351,"context_line":"                set_delete_at_headers(n_outgoing - 1 - index, next(dan_iter))"},{"line_number":352,"context_line":"            existing_updates +\u003d 1"},{"line_number":353,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_d9b29894","line":350,"updated":"2018-01-17 01:45:06.000000000","message":"+1, good call.","commit_id":"a7c919e338c3f527fc8fc3a61fe25151ee4f6cf8"}],"test/unit/obj/test_server.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3c43143af6a033868bf0e7a9697ca79642351e55","unresolved":false,"context_lines":[{"line_number":5582,"context_line":"                     \u0027X-Backend-Storage-Policy-Index\u0027: int(policy)})"},{"line_number":5583,"context_line":"        self.object_controller.delete_at_update(\u0027PUT\u0027, 2, \u0027a\u0027, \u0027c\u0027, \u0027o\u0027,"},{"line_number":5584,"context_line":"                                                req, \u0027sda1\u0027, policy)"},{"line_number":5585,"context_line":"        self.assertEqual(given_args, [])"},{"line_number":5586,"context_line":""},{"line_number":5587,"context_line":"    def test_delete_at_update_delete(self):"},{"line_number":5588,"context_line":"        policy \u003d random.choice(list(POLICIES))"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_196a40ec","line":5585,"updated":"2018-01-17 01:45:06.000000000","message":"Oops! Glad we\u0027re adding assertions about this :D","commit_id":"a7c919e338c3f527fc8fc3a61fe25151ee4f6cf8"}],"test/unit/proxy/controllers/test_obj.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"156b093c4b2eb1df8fcbb9b005b7764cd8d26f56","unresolved":false,"context_lines":[{"line_number":1405,"context_line":"            self.assertIn(\u0027X-Delete-At-Partition\u0027, given_headers)"},{"line_number":1406,"context_line":"            self.assertIn(\u0027X-Delete-At-Container\u0027, given_headers)"},{"line_number":1407,"context_line":""},{"line_number":1408,"context_line":"    def test_PUT_delete_at_more_replicas(self):"},{"line_number":1409,"context_line":"        # Case object replicas \u003e container replicas. See bug 1733588 ."},{"line_number":1410,"context_line":"        self.obj_ring.set_replicas(4)"},{"line_number":1411,"context_line":"        t \u003d str(int(time.time() + 100))"}],"source_content_type":"text/x-python","patch_set":2,"id":"df87a7cf_1571e8e0","line":1408,"range":{"start_line":1408,"start_character":8,"end_line":1408,"end_character":40},"updated":"2017-12-06 01:59:13.000000000","message":"it would be good if this test was in BaseObjectControllerMixin so that we test both replicated and EC policy object controller paths\n\nfor example, see https://github.com/openstack/swift/blob/459f5efcd7cefaf65f898d27ab52d7ddaa65e2d0/test/unit/proxy/controllers/test_obj.py#L660-L692","commit_id":"459f5efcd7cefaf65f898d27ab52d7ddaa65e2d0"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"156b093c4b2eb1df8fcbb9b005b7764cd8d26f56","unresolved":false,"context_lines":[{"line_number":1421,"context_line":"        codes \u003d [201] * self.obj_ring.replicas"},{"line_number":1422,"context_line":"        with set_http_connect(*codes, give_connect\u003dcapture_headers):"},{"line_number":1423,"context_line":"            resp \u003d req.get_response(self.app)"},{"line_number":1424,"context_line":"        self.assertEqual(resp.status_int, 201)"},{"line_number":1425,"context_line":"        for given_headers in put_headers:"},{"line_number":1426,"context_line":"            self.assertEqual(given_headers.get(\u0027X-Delete-At\u0027), t)"},{"line_number":1427,"context_line":"            self.assertIn(\u0027X-Delete-At-Host\u0027, given_headers)"}],"source_content_type":"text/x-python","patch_set":2,"id":"df87a7cf_95a73850","line":1424,"updated":"2017-12-06 01:59:13.000000000","message":"I think it would be worth asserting that 4 sets of headers have been captured","commit_id":"459f5efcd7cefaf65f898d27ab52d7ddaa65e2d0"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3c43143af6a033868bf0e7a9697ca79642351e55","unresolved":false,"context_lines":[{"line_number":799,"context_line":""},{"line_number":800,"context_line":"            for num_del_at_nodes in range(1, 16):"},{"line_number":801,"context_line":"                containers \u003d ["},{"line_number":802,"context_line":"                    {\u0027ip\u0027: \u00272.0.0.%s\u0027 % i, \u0027port\u0027: \u002770%s\u0027 % str(i).zfill(2),"},{"line_number":803,"context_line":"                     \u0027device\u0027: \u0027sdc\u0027} for i in range(num_del_at_nodes)]"},{"line_number":804,"context_line":"                del_at_nodes \u003d ["},{"line_number":805,"context_line":"                    {\u0027ip\u0027: \u00271.0.0.%s\u0027 % i, \u0027port\u0027: \u002760%s\u0027 % str(i).zfill(2),"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_5c851659","line":802,"range":{"start_line":802,"start_character":54,"end_line":802,"end_character":75},"updated":"2018-01-17 01:45:06.000000000","message":"nit: or, use %02d","commit_id":"a7c919e338c3f527fc8fc3a61fe25151ee4f6cf8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3c43143af6a033868bf0e7a9697ca79642351e55","unresolved":false,"context_lines":[{"line_number":823,"context_line":"                        self.assertEqual("},{"line_number":824,"context_line":"                            given_headers.get(\u0027X-Delete-At-Container\u0027), \u0027dac\u0027)"},{"line_number":825,"context_line":"                        ctr +\u003d 1"},{"line_number":826,"context_line":"                    devices +\u003d ("},{"line_number":827,"context_line":"                        list_from_csv(given_headers.get(\u0027X-Delete-At-Device\u0027)))"},{"line_number":828,"context_line":"                    hosts +\u003d ("},{"line_number":829,"context_line":"                        list_from_csv(given_headers.get(\u0027X-Delete-At-Host\u0027)))"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_5cbd16d6","line":826,"range":{"start_line":826,"start_character":28,"end_line":826,"end_character":30},"updated":"2018-01-17 01:45:06.000000000","message":"nit: better with extend()","commit_id":"a7c919e338c3f527fc8fc3a61fe25151ee4f6cf8"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3c43143af6a033868bf0e7a9697ca79642351e55","unresolved":false,"context_lines":[{"line_number":890,"context_line":"                # the x-delete-at* headers"},{"line_number":891,"context_line":"                self.assertTrue("},{"line_number":892,"context_line":"                    all([h.get(\u0027X-Delete-At-Container\u0027)"},{"line_number":893,"context_line":"                         for h in backend_headers[-n_expected_updates:]]))"},{"line_number":894,"context_line":""},{"line_number":895,"context_line":"    def _check_write_affinity("},{"line_number":896,"context_line":"            self, conf, policy_conf, policy, affinity_regions, affinity_count):"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_7ca7b2be","line":893,"updated":"2018-01-17 01:45:06.000000000","message":"Maybe worth having the complements, too?\n\n self.assertFalse(\n     any(h.get(\u0027X-Container-Partition\u0027)\n         for h in backend_headers[n_expected_updates:]))\n self.assertFalse(\n     any(h.get(\u0027X-Delete-At-Container\u0027)\n         for h in backend_headers[:-n_expected_updates]))","commit_id":"a7c919e338c3f527fc8fc3a61fe25151ee4f6cf8"}],"test/unit/proxy/test_server.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3c43143af6a033868bf0e7a9697ca79642351e55","unresolved":false,"context_lines":[{"line_number":5489,"context_line":"             \u0027X-Delete-At-Partition\u0027: None,"},{"line_number":5490,"context_line":"             \u0027X-Delete-At-Container\u0027: None,"},{"line_number":5491,"context_line":"             \u0027X-Delete-At-Device\u0027: None},"},{"line_number":5492,"context_line":"        ])"},{"line_number":5493,"context_line":""},{"line_number":5494,"context_line":"    @mock.patch(\u0027time.time\u0027, new\u003dlambda: STATIC_TIME)"},{"line_number":5495,"context_line":"    def test_PUT_x_delete_at_with_more_container_replicas(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"7f96bb07_997df0b3","line":5492,"updated":"2018-01-17 01:45:06.000000000","message":"nit: Unnecessary delta?","commit_id":"a7c919e338c3f527fc8fc3a61fe25151ee4f6cf8"}]}
