)]}'
{"swift/proxy/controllers/container.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f3b5eb9283a77f083f7d6b94961a401f6b93f43","unresolved":true,"context_lines":[{"line_number":160,"context_line":"        #      shard may return the root\u0027s shard range."},{"line_number":161,"context_line":"        shard_listing_history \u003d req.environ.setdefault("},{"line_number":162,"context_line":"            \u0027swift.shard_listing_history\u0027, [])"},{"line_number":163,"context_line":"        shard_listing_history.append((self.account_name, self.container_name))"},{"line_number":164,"context_line":"        shard_ranges \u003d [ShardRange.from_dict(data)"},{"line_number":165,"context_line":"                        for data in json.loads(resp.body)]"},{"line_number":166,"context_line":"        self.app.logger.debug(\u0027GET listing from %s shards for: %s\u0027,"}],"source_content_type":"text/x-python","patch_set":3,"id":"0290043e_cbe08ef0","line":163,"updated":"2021-01-05 21:40:43.000000000","message":"self in this context is for whoever we\u0027re making THIS request (i.e. account_name might be just \"a\" or \".shards_a\")","commit_id":"5a5980e9c4f640e0e99b970ab14431c48be03a60"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f3b5eb9283a77f083f7d6b94961a401f6b93f43","unresolved":true,"context_lines":[{"line_number":181,"context_line":"        prefix \u003d wsgi_to_str(params.get(\u0027prefix\u0027))"},{"line_number":182,"context_line":""},{"line_number":183,"context_line":"        limit \u003d req_limit"},{"line_number":184,"context_line":"        for shard_range in shard_ranges:"},{"line_number":185,"context_line":"            params[\u0027limit\u0027] \u003d limit"},{"line_number":186,"context_line":"            # Always set marker to ensure that object names less than or equal"},{"line_number":187,"context_line":"            # to those already in the listing are not fetched; if the listing"}],"source_content_type":"text/x-python","patch_set":3,"id":"f881952a_70697fbb","line":184,"updated":"2021-01-05 21:40:43.000000000","message":"so we go through all the shard ranges in the response and make \"at least\" one request to get the list of with-in that range","commit_id":"5a5980e9c4f640e0e99b970ab14431c48be03a60"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f3b5eb9283a77f083f7d6b94961a401f6b93f43","unresolved":true,"context_lines":[{"line_number":209,"context_line":""},{"line_number":210,"context_line":"            if ((shard_range.account, shard_range.container) in"},{"line_number":211,"context_line":"                    shard_listing_history):"},{"line_number":212,"context_line":"                # directed back to same container - force GET of objects"},{"line_number":213,"context_line":"                headers \u003d {\u0027X-Backend-Record-Type\u0027: \u0027object\u0027}"},{"line_number":214,"context_line":"            else:"},{"line_number":215,"context_line":"                headers \u003d None"}],"source_content_type":"text/x-python","patch_set":3,"id":"80486a85_79a37ca7","line":212,"updated":"2021-01-05 21:40:43.000000000","message":"this is ... really obvious, quite nice 👍","commit_id":"5a5980e9c4f640e0e99b970ab14431c48be03a60"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f3b5eb9283a77f083f7d6b94961a401f6b93f43","unresolved":true,"context_lines":[{"line_number":229,"context_line":"                                  shard_range, shard_range.name, headers)"},{"line_number":230,"context_line":"            objs, shard_resp \u003d self._get_container_listing("},{"line_number":231,"context_line":"                req, shard_range.account, shard_range.container,"},{"line_number":232,"context_line":"                headers\u003dheaders, params\u003dparams)"},{"line_number":233,"context_line":""},{"line_number":234,"context_line":"            if not objs:"},{"line_number":235,"context_line":"                # tolerate errors or empty shard containers"}],"source_content_type":"text/x-python","patch_set":3,"id":"62b1384a_ab3e7fcc","line":232,"updated":"2021-01-05 21:40:43.000000000","message":"this function is in base, but it can \"recurse\" into this method through handle_request and GETorHEAD","commit_id":"5a5980e9c4f640e0e99b970ab14431c48be03a60"}],"test/unit/proxy/controllers/test_container.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f3b5eb9283a77f083f7d6b94961a401f6b93f43","unresolved":true,"context_lines":[{"line_number":658,"context_line":"                  limit\u003dstr(limit - len(sr_objs[0])))),  # 200"},{"line_number":659,"context_line":"            (root_range.name, {\u0027X-Backend-Record-Type\u0027: \u0027object\u0027},"},{"line_number":660,"context_line":"             dict(marker\u003d\u0027p\u0027, end_marker\u003d\u0027\u0027,"},{"line_number":661,"context_line":"                  limit\u003dstr(limit - len(sr_objs[0] + sr_objs[1]))))  # 200"},{"line_number":662,"context_line":"        ]"},{"line_number":663,"context_line":""},{"line_number":664,"context_line":"        resp \u003d self._check_GET_shard_listing("}],"source_content_type":"text/x-python","patch_set":3,"id":"a6a8296b_c349d441","line":661,"updated":"2021-01-05 21:40:43.000000000","message":"this was testing the original path, where we\u0027d request back to the *root* (you can see the backend-record-type is object)","commit_id":"5a5980e9c4f640e0e99b970ab14431c48be03a60"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b4f8cb5822f5105f49a482c28781de9e66301a07","unresolved":false,"context_lines":[{"line_number":658,"context_line":"                  limit\u003dstr(limit - len(sr_objs[0])))),  # 200"},{"line_number":659,"context_line":"            (root_range.name, {\u0027X-Backend-Record-Type\u0027: \u0027object\u0027},"},{"line_number":660,"context_line":"             dict(marker\u003d\u0027p\u0027, end_marker\u003d\u0027\u0027,"},{"line_number":661,"context_line":"                  limit\u003dstr(limit - len(sr_objs[0] + sr_objs[1]))))  # 200"},{"line_number":662,"context_line":"        ]"},{"line_number":663,"context_line":""},{"line_number":664,"context_line":"        resp \u003d self._check_GET_shard_listing("}],"source_content_type":"text/x-python","patch_set":3,"id":"06210af1_906aa7f8","line":661,"in_reply_to":"a6a8296b_c349d441","updated":"2021-01-06 16:18:43.000000000","message":"Ack","commit_id":"5a5980e9c4f640e0e99b970ab14431c48be03a60"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f3b5eb9283a77f083f7d6b94961a401f6b93f43","unresolved":true,"context_lines":[{"line_number":969,"context_line":"        # check that if the root redirects listing to a shard, but the shard"},{"line_number":970,"context_line":"        # returns the root shard (e.g. it was the final shard to shrink into"},{"line_number":971,"context_line":"        # the root) objects are requested from the root, rather than a loop"},{"line_number":972,"context_line":"        shard_bounds \u003d (\u0027\u0027, \u0027\u0027)"},{"line_number":973,"context_line":"        shard_ranges \u003d ["},{"line_number":974,"context_line":"            ShardRange(\u0027.shards_a/c_%s\u0027 % upper, Timestamp.now(), lower, upper)"},{"line_number":975,"context_line":"            for lower, upper in zip(shard_bounds[:-1], shard_bounds[1:])]"}],"source_content_type":"text/x-python","patch_set":3,"id":"58b255da_43894b2e","line":972,"updated":"2021-01-05 21:40:43.000000000","message":"is this like... just one shard range?  MIN-MAX?","commit_id":"5a5980e9c4f640e0e99b970ab14431c48be03a60"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b4f8cb5822f5105f49a482c28781de9e66301a07","unresolved":false,"context_lines":[{"line_number":969,"context_line":"        # check that if the root redirects listing to a shard, but the shard"},{"line_number":970,"context_line":"        # returns the root shard (e.g. it was the final shard to shrink into"},{"line_number":971,"context_line":"        # the root) objects are requested from the root, rather than a loop"},{"line_number":972,"context_line":"        shard_bounds \u003d (\u0027\u0027, \u0027\u0027)"},{"line_number":973,"context_line":"        shard_ranges \u003d ["},{"line_number":974,"context_line":"            ShardRange(\u0027.shards_a/c_%s\u0027 % upper, Timestamp.now(), lower, upper)"},{"line_number":975,"context_line":"            for lower, upper in zip(shard_bounds[:-1], shard_bounds[1:])]"}],"source_content_type":"text/x-python","patch_set":3,"id":"cda33d9b_bbb55937","line":972,"in_reply_to":"58b255da_43894b2e","updated":"2021-01-06 16:18:43.000000000","message":"yes, when all other shards have shrunk away, the final shard has the entire namespace","commit_id":"5a5980e9c4f640e0e99b970ab14431c48be03a60"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"5f3b5eb9283a77f083f7d6b94961a401f6b93f43","unresolved":true,"context_lines":[{"line_number":1000,"context_line":"        root_shard_resp_hdrs \u003d dict(root_resp_hdrs)"},{"line_number":1001,"context_line":"        root_shard_resp_hdrs[\u0027X-Backend-Record-Type\u0027] \u003d \u0027shard\u0027"},{"line_number":1002,"context_line":""},{"line_number":1003,"context_line":"        root_sr \u003d ShardRange(\u0027a/c\u0027, Timestamp.now(), \u0027, \u0027)"},{"line_number":1004,"context_line":"        mock_responses \u003d ["},{"line_number":1005,"context_line":"            # status, body, headers"},{"line_number":1006,"context_line":"            (200, sr_dicts, root_shard_resp_hdrs),"}],"source_content_type":"text/x-python","patch_set":3,"id":"afa5f61e_5a67e55c","line":1003,"updated":"2021-01-05 21:40:43.000000000","message":"this is ... less obvious.\n\nThe ommited \"upper\" param means this shard range goes to MAX from... the bound of \"a literal comma\"?","commit_id":"5a5980e9c4f640e0e99b970ab14431c48be03a60"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b4f8cb5822f5105f49a482c28781de9e66301a07","unresolved":false,"context_lines":[{"line_number":1000,"context_line":"        root_shard_resp_hdrs \u003d dict(root_resp_hdrs)"},{"line_number":1001,"context_line":"        root_shard_resp_hdrs[\u0027X-Backend-Record-Type\u0027] \u003d \u0027shard\u0027"},{"line_number":1002,"context_line":""},{"line_number":1003,"context_line":"        root_sr \u003d ShardRange(\u0027a/c\u0027, Timestamp.now(), \u0027, \u0027)"},{"line_number":1004,"context_line":"        mock_responses \u003d ["},{"line_number":1005,"context_line":"            # status, body, headers"},{"line_number":1006,"context_line":"            (200, sr_dicts, root_shard_resp_hdrs),"}],"source_content_type":"text/x-python","patch_set":3,"id":"c034b580_5d468b05","line":1003,"in_reply_to":"afa5f61e_5a67e55c","updated":"2021-01-06 16:18:43.000000000","message":"oops, that\u0027s a typo! should be \u0027\u0027, \u0027\u0027","commit_id":"5a5980e9c4f640e0e99b970ab14431c48be03a60"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"04642d0e4b65407842b18690b2e2a59efb18542d","unresolved":true,"context_lines":[{"line_number":1014,"context_line":"             dict(marker\u003d\u0027\u0027, end_marker\u003d\u0027\u0027, limit\u003dstr(limit),"},{"line_number":1015,"context_line":"                  states\u003d\u0027listing\u0027)),  # 200"},{"line_number":1016,"context_line":"            # second request to root should specify object record type"},{"line_number":1017,"context_line":"            (\u0027a/c\u0027, {\u0027X-Backend-Record-Type\u0027: \u0027object\u0027},"},{"line_number":1018,"context_line":"             dict(marker\u003d\u0027\u0027, end_marker\u003d\u0027\u0027, limit\u003dstr(limit))),  # 200"},{"line_number":1019,"context_line":"        ]"},{"line_number":1020,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"ecdcce9d_2c926406","line":1017,"updated":"2021-01-06 16:35:25.000000000","message":"it\u0027s subtle, but in this context the existing check didn\u0027t prevent us going back to the root with auto - because in that situation the \"self\" was the shard","commit_id":"453983764727ba528222a413691a0f0fc5a8f8cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"04642d0e4b65407842b18690b2e2a59efb18542d","unresolved":true,"context_lines":[{"line_number":1115,"context_line":"            (\u0027.shards_a/c_\u0027, {\u0027X-Backend-Record-Type\u0027: \u0027object\u0027},"},{"line_number":1116,"context_line":"             dict(marker\u003d\u0027b\u0027, end_marker\u003d\u0027\u0027,"},{"line_number":1117,"context_line":"                  limit\u003dstr("},{"line_number":1118,"context_line":"                      limit - len(sr_objs[0]) - len(sr_objs[1])))),  # 200"},{"line_number":1119,"context_line":"        ]"},{"line_number":1120,"context_line":"        resp \u003d self._check_GET_shard_listing("},{"line_number":1121,"context_line":"            mock_responses, all_objects, expected_requests)"}],"source_content_type":"text/x-python","patch_set":5,"id":"4503c5a2_2445e0d2","line":1118,"updated":"2021-01-06 16:35:25.000000000","message":"I really like the way this test demonstrates that anytime we \"go back\" to make a listing to to a shard that had *previously retruned shards* - we\u0027ll always specify objects 👍","commit_id":"453983764727ba528222a413691a0f0fc5a8f8cf"}]}
