)]}'
{"swift/container/sharder.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"adebfa2ba0fedfa6274d679a5fed10c77bdbfdef","unresolved":false,"context_lines":[{"line_number":209,"context_line":"        self.misplaced_done \u003d misplaced_done"},{"line_number":210,"context_line":"        self.ranges_done \u003d ranges_done"},{"line_number":211,"context_line":"        self.ranges_todo \u003d ranges_todo"},{"line_number":212,"context_line":"        self.last_modified \u003d last_modified"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"    def __iter__(self):"},{"line_number":215,"context_line":"        yield \u0027ref\u0027, self.ref"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_573565d9","line":212,"updated":"2019-09-19 06:22:47.000000000","message":"So I realized -- technically, we already store this -- it\u0027s the write timestamp for the piece of metadata. But maybe actually *getting at* that is (and should be) outside of the scope of this bug.\n\nPlus it lets us set up tests at least slightly more easily ;-)","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"eb6ef2995c4c1ddca4aba3b249b2556db876b476","unresolved":false,"context_lines":[{"line_number":209,"context_line":"        self.misplaced_done \u003d misplaced_done"},{"line_number":210,"context_line":"        self.ranges_done \u003d ranges_done"},{"line_number":211,"context_line":"        self.ranges_todo \u003d ranges_todo"},{"line_number":212,"context_line":"        self.last_modified \u003d last_modified"},{"line_number":213,"context_line":""},{"line_number":214,"context_line":"    def __iter__(self):"},{"line_number":215,"context_line":"        yield \u0027ref\u0027, self.ref"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_db80978e","line":212,"in_reply_to":"3fa7e38b_573565d9","updated":"2019-09-19 16:34:19.000000000","message":"Oh hey -- acoles had the same idea! https://review.opendev.org/#/c/569832/","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ad429cdfc251f9bccdfc74f4734d93ade37b78c3","unresolved":false,"context_lines":[{"line_number":261,"context_line":"            if key.startswith(\"Context-\") and len(val) \u003e 0:"},{"line_number":262,"context_line":"                try:"},{"line_number":263,"context_line":"                    yield cls(**json.loads(val))"},{"line_number":264,"context_line":"                except ValueError:"},{"line_number":265,"context_line":"                    continue"},{"line_number":266,"context_line":""},{"line_number":267,"context_line":"    @classmethod"},{"line_number":268,"context_line":"    def load(cls, broker):"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_cc877c61","line":265,"range":{"start_line":264,"start_character":16,"end_line":265,"end_character":28},"updated":"2019-09-19 23:58:05.000000000","message":"Is this mainly for corrupted (but non-empty) values getting passed to json.loads(), or is there something else I\u0027m not thinking of?","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"adebfa2ba0fedfa6274d679a5fed10c77bdbfdef","unresolved":false,"context_lines":[{"line_number":311,"context_line":"        return all((self.misplaced_done, self.cleaving_done,"},{"line_number":312,"context_line":"                    self.max_row \u003d\u003d self.cleave_to_row))"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"    def delete(self, broker):"},{"line_number":315,"context_line":"        # These will get reclaimed when `_reclaim_metadata` in"},{"line_number":316,"context_line":"        # common/db.py is called."},{"line_number":317,"context_line":"        broker.set_sharding_sysmeta(\u0027Context-\u0027 + self.ref, \u0027\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_d72155a1","line":314,"updated":"2019-09-19 06:22:47.000000000","message":"This API feels slightly backwards to me -- like, the context got loaded/created within the context of a broker, so the fact that we have to pass a broker in here... idk, it feels a little goofy.\n\nBut w/e, bug is buggy, and this fixes it. Swift gets better.","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ad429cdfc251f9bccdfc74f4734d93ade37b78c3","unresolved":false,"context_lines":[{"line_number":311,"context_line":"        return all((self.misplaced_done, self.cleaving_done,"},{"line_number":312,"context_line":"                    self.max_row \u003d\u003d self.cleave_to_row))"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"    def delete(self, broker):"},{"line_number":315,"context_line":"        # These will get reclaimed when `_reclaim_metadata` in"},{"line_number":316,"context_line":"        # common/db.py is called."},{"line_number":317,"context_line":"        broker.set_sharding_sysmeta(\u0027Context-\u0027 + self.ref, \u0027\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_671d410e","line":314,"in_reply_to":"3fa7e38b_d72155a1","updated":"2019-09-19 23:58:05.000000000","message":"Y\u0027know, I take it back -- we\u0027re just matching precedent with the store() API here.","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"21e351771ea7f5119d65493cef566daed4c80076","unresolved":false,"context_lines":[{"line_number":314,"context_line":"    def delete(self, broker):"},{"line_number":315,"context_line":"        # These will get reclaimed when `_reclaim_metadata` in"},{"line_number":316,"context_line":"        # common/db.py is called."},{"line_number":317,"context_line":"        broker.set_sharding_sysmeta(\u0027Context-\u0027 + self.ref, \u0027\u0027)"},{"line_number":318,"context_line":""},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"DEFAULT_SHARD_CONTAINER_THRESHOLD \u003d 1000000"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_2ebc1ddb","line":317,"updated":"2019-09-18 21:37:28.000000000","message":"so delete doesn\u0027t actually reap anything?  does reap now require this sysmeta?","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"adebfa2ba0fedfa6274d679a5fed10c77bdbfdef","unresolved":false,"context_lines":[{"line_number":314,"context_line":"    def delete(self, broker):"},{"line_number":315,"context_line":"        # These will get reclaimed when `_reclaim_metadata` in"},{"line_number":316,"context_line":"        # common/db.py is called."},{"line_number":317,"context_line":"        broker.set_sharding_sysmeta(\u0027Context-\u0027 + self.ref, \u0027\u0027)"},{"line_number":318,"context_line":""},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"DEFAULT_SHARD_CONTAINER_THRESHOLD \u003d 1000000"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_c4ae852d","line":317,"in_reply_to":"3fa7e38b_042d7d42","updated":"2019-09-19 06:22:47.000000000","message":"Yeah, as long as the value is blank (or, technically, false-y) it\u0027ll get dropped from the response and not count against max_meta_count, right? https://github.com/openstack/swift/blob/2.22.0/swift/container/server.py#L710\n\nIn the meantime, we want to make sure the removal gets replicated out, right?","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"fdf5fdd0f41448d5accde93ce66a1043a4f4dff1","unresolved":false,"context_lines":[{"line_number":314,"context_line":"    def delete(self, broker):"},{"line_number":315,"context_line":"        # These will get reclaimed when `_reclaim_metadata` in"},{"line_number":316,"context_line":"        # common/db.py is called."},{"line_number":317,"context_line":"        broker.set_sharding_sysmeta(\u0027Context-\u0027 + self.ref, \u0027\u0027)"},{"line_number":318,"context_line":""},{"line_number":319,"context_line":""},{"line_number":320,"context_line":"DEFAULT_SHARD_CONTAINER_THRESHOLD \u003d 1000000"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_042d7d42","line":317,"in_reply_to":"3fa7e38b_2ebc1ddb","updated":"2019-09-19 05:28:34.000000000","message":"Yeah, the reclaim_metadata (https://github.com/openstack/swift/blob/master/swift/common/db.py#L986) will go reap old metadata that has a value of \"\".\n\nI didn\u0027t want to go reach and fiddle with the container metadata internals.\n\nIn a normal case, I think this is enough. At least it\u0027s marked to be deleted. Although doesn\u0027t speed up deleting if there are thousands of entries. Although, I hope that the fact that the value is \u0027\u0027 they\u0027ll be skipped as that is suppose to mean they\u0027ve been marked as deleted.","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"21e351771ea7f5119d65493cef566daed4c80076","unresolved":false,"context_lines":[{"line_number":754,"context_line":"        return True"},{"line_number":755,"context_line":""},{"line_number":756,"context_line":"    def _audit_cleave_contexts(self, broker):"},{"line_number":757,"context_line":"        for context in CleavingContext.load_all(broker):"},{"line_number":758,"context_line":"            now \u003d Timestamp.now()"},{"line_number":759,"context_line":"            last_mod \u003d context.last_modified"},{"line_number":760,"context_line":"            if not last_mod:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_aef80dc4","line":757,"updated":"2019-09-18 21:37:28.000000000","message":"what\u0027s the cardinality here?  10\u0027s 1000\u0027s?  MILLIONS!?","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"adebfa2ba0fedfa6274d679a5fed10c77bdbfdef","unresolved":false,"context_lines":[{"line_number":754,"context_line":"        return True"},{"line_number":755,"context_line":""},{"line_number":756,"context_line":"    def _audit_cleave_contexts(self, broker):"},{"line_number":757,"context_line":"        for context in CleavingContext.load_all(broker):"},{"line_number":758,"context_line":"            now \u003d Timestamp.now()"},{"line_number":759,"context_line":"            last_mod \u003d context.last_modified"},{"line_number":760,"context_line":"            if not last_mod:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_244c399d","line":757,"in_reply_to":"3fa7e38b_84ededf0","updated":"2019-09-19 06:22:47.000000000","message":"In the steady-state after a fix, replica_count. While cleaning up from old, bug-ridden Swift, we\u0027ve seen containers hit some 1200, 1300 total entries, which is ~10x the defaul max_meta_count.","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"fdf5fdd0f41448d5accde93ce66a1043a4f4dff1","unresolved":false,"context_lines":[{"line_number":754,"context_line":"        return True"},{"line_number":755,"context_line":""},{"line_number":756,"context_line":"    def _audit_cleave_contexts(self, broker):"},{"line_number":757,"context_line":"        for context in CleavingContext.load_all(broker):"},{"line_number":758,"context_line":"            now \u003d Timestamp.now()"},{"line_number":759,"context_line":"            last_mod \u003d context.last_modified"},{"line_number":760,"context_line":"            if not last_mod:"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_84ededf0","line":757,"in_reply_to":"3fa7e38b_aef80dc4","updated":"2019-09-19 05:28:34.000000000","message":"To be honest, I\u0027d expect it to be \u003c 10\u0027s. The bug in question is interesting, as they would\u0027ve had a slow or error limitted root container, so new empty containers might have been created on handoffs.. which then failed to shard fast enough (because currently we don\u0027t skip empty shard ranges). Leading to more and more CleaveContexts.\n\nSo we know NM had _alot_.\n\nIn general, I\u0027d expect the number to generally be number of primaries in a perfect world. Plus some for rebalances and/or handoffs if that happens during sharding... so worse on large containers I suspect.\n\nA cleavecontext uses the db ID as a reference, to keep track of that sharding. That only changes on handoffs, rebalances or maybe rsync+merge if I remember correctly.","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"adebfa2ba0fedfa6274d679a5fed10c77bdbfdef","unresolved":false,"context_lines":[{"line_number":755,"context_line":""},{"line_number":756,"context_line":"    def _audit_cleave_contexts(self, broker):"},{"line_number":757,"context_line":"        for context in CleavingContext.load_all(broker):"},{"line_number":758,"context_line":"            now \u003d Timestamp.now()"},{"line_number":759,"context_line":"            last_mod \u003d context.last_modified"},{"line_number":760,"context_line":"            if not last_mod:"},{"line_number":761,"context_line":"                context.store(broker)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_241af97c","line":758,"updated":"2019-09-19 06:22:47.000000000","message":"nit: This could get hoisted up \u0026 out of the for-loop","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"adebfa2ba0fedfa6274d679a5fed10c77bdbfdef","unresolved":false,"context_lines":[{"line_number":757,"context_line":"        for context in CleavingContext.load_all(broker):"},{"line_number":758,"context_line":"            now \u003d Timestamp.now()"},{"line_number":759,"context_line":"            last_mod \u003d context.last_modified"},{"line_number":760,"context_line":"            if not last_mod:"},{"line_number":761,"context_line":"                context.store(broker)"},{"line_number":762,"context_line":"            elif Timestamp(last_mod).timestamp + self.reclaim_age \u003c \\"},{"line_number":763,"context_line":"                    now.timestamp:"},{"line_number":764,"context_line":"                context.delete(broker)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_c421a5b6","line":761,"range":{"start_line":760,"start_character":11,"end_line":761,"end_character":37},"updated":"2019-09-19 06:22:47.000000000","message":"Right, so here\u0027s our migration to add a last_modified if it doesn\u0027t already exist...","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"21e351771ea7f5119d65493cef566daed4c80076","unresolved":false,"context_lines":[{"line_number":761,"context_line":"                context.store(broker)"},{"line_number":762,"context_line":"            elif Timestamp(last_mod).timestamp + self.reclaim_age \u003c \\"},{"line_number":763,"context_line":"                    now.timestamp:"},{"line_number":764,"context_line":"                context.delete(broker)"},{"line_number":765,"context_line":""},{"line_number":766,"context_line":"    def _audit_container(self, broker):"},{"line_number":767,"context_line":"        if broker.is_deleted():"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_0e2da142","line":764,"updated":"2019-09-18 21:37:28.000000000","message":"is this *only* to catch the old stuff - going forward do we mostly expect it should more or less always get caught when it finishes?","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"fdf5fdd0f41448d5accde93ce66a1043a4f4dff1","unresolved":false,"context_lines":[{"line_number":761,"context_line":"                context.store(broker)"},{"line_number":762,"context_line":"            elif Timestamp(last_mod).timestamp + self.reclaim_age \u003c \\"},{"line_number":763,"context_line":"                    now.timestamp:"},{"line_number":764,"context_line":"                context.delete(broker)"},{"line_number":765,"context_line":""},{"line_number":766,"context_line":"    def _audit_container(self, broker):"},{"line_number":767,"context_line":"        if broker.is_deleted():"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_a4cfc97d","line":764,"in_reply_to":"3fa7e38b_0e2da142","updated":"2019-09-19 05:28:34.000000000","message":"exactly, this is just for garbage collection. When a db enters SHARDING state it should be deleted. When the skip empty shards patch lands. I hope that sharding empty containers will shard quickly and therefore deleted quickly... so hopefully garbage collection becomes less and less.","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ad429cdfc251f9bccdfc74f4734d93ade37b78c3","unresolved":false,"context_lines":[{"line_number":761,"context_line":"                context.store(broker)"},{"line_number":762,"context_line":"            elif Timestamp(last_mod).timestamp + self.reclaim_age \u003c \\"},{"line_number":763,"context_line":"                    now.timestamp:"},{"line_number":764,"context_line":"                context.delete(broker)"},{"line_number":765,"context_line":""},{"line_number":766,"context_line":"    def _audit_container(self, broker):"},{"line_number":767,"context_line":"        if broker.is_deleted():"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_c7bc35de","line":764,"in_reply_to":"3fa7e38b_a4cfc97d","updated":"2019-09-19 23:58:05.000000000","message":"Also worth noting: the penalty for accidentally deleting a context that shouldn\u0027t have been deleted is reasonably low. We won\u0027t lose data, but we can reset cleaving progress. As long as you configure reclaim_age higher than your sharder cycle times, you should be fine.\n\nNote that even after this fix, there\u0027s a chance for this path to get triggered -- for example, if the sharder process crashes between unlinking the old DB and clearing the sysmeta.","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"21e351771ea7f5119d65493cef566daed4c80076","unresolved":false,"context_lines":[{"line_number":769,"context_line":"            # have been erased so no point auditing. But we want it to pass, in"},{"line_number":770,"context_line":"            # case any objects exist inside it."},{"line_number":771,"context_line":"            return True"},{"line_number":772,"context_line":"        self._audit_cleave_contexts(broker)"},{"line_number":773,"context_line":"        if broker.is_root_container():"},{"line_number":774,"context_line":"            return self._audit_root_container(broker)"},{"line_number":775,"context_line":"        return self._audit_shard_container(broker)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_4e3399ac","line":772,"updated":"2019-09-18 21:37:28.000000000","message":"and we call this regardless of shard/root status - because shard can cleave sometimes?","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"fdf5fdd0f41448d5accde93ce66a1043a4f4dff1","unresolved":false,"context_lines":[{"line_number":769,"context_line":"            # have been erased so no point auditing. But we want it to pass, in"},{"line_number":770,"context_line":"            # case any objects exist inside it."},{"line_number":771,"context_line":"            return True"},{"line_number":772,"context_line":"        self._audit_cleave_contexts(broker)"},{"line_number":773,"context_line":"        if broker.is_root_container():"},{"line_number":774,"context_line":"            return self._audit_root_container(broker)"},{"line_number":775,"context_line":"        return self._audit_shard_container(broker)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_64c9d176","line":772,"in_reply_to":"3fa7e38b_4e3399ac","updated":"2019-09-19 05:28:34.000000000","message":"yeah, a root obviously cleave.. but so should shards when they get too big. So I assume we should garbage collect everywhere.","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"21e351771ea7f5119d65493cef566daed4c80076","unresolved":false,"context_lines":[{"line_number":1347,"context_line":"            modified_shard_ranges.append(own_shard_range)"},{"line_number":1348,"context_line":"            broker.merge_shard_ranges(modified_shard_ranges)"},{"line_number":1349,"context_line":"            if broker.set_sharded_state():"},{"line_number":1350,"context_line":"                cleaving_context.delete(broker)"},{"line_number":1351,"context_line":"                return True"},{"line_number":1352,"context_line":"            else:"},{"line_number":1353,"context_line":"                self.logger.warning("}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_6e6d3597","line":1350,"updated":"2019-09-18 21:37:28.000000000","message":"so this is a proactive delete going forward?","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"fdf5fdd0f41448d5accde93ce66a1043a4f4dff1","unresolved":false,"context_lines":[{"line_number":1347,"context_line":"            modified_shard_ranges.append(own_shard_range)"},{"line_number":1348,"context_line":"            broker.merge_shard_ranges(modified_shard_ranges)"},{"line_number":1349,"context_line":"            if broker.set_sharded_state():"},{"line_number":1350,"context_line":"                cleaving_context.delete(broker)"},{"line_number":1351,"context_line":"                return True"},{"line_number":1352,"context_line":"            else:"},{"line_number":1353,"context_line":"                self.logger.warning("}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_a494a945","line":1350,"in_reply_to":"3fa7e38b_6e6d3597","updated":"2019-09-19 05:28:34.000000000","message":"Yeah.\n\nI figure, currently we don\u0027t seem to clean them up. When shards cleave, they can delete themselves. But I think these CleaveContexts stick around.. forever.. in the root. We could not proactive delete and let the garbage collecting do that job. Or we can be proactive, because we just unlinked the retiring DB here. As far as this particular DB is concerned it\u0027s done and wont need its context anymore.\n\nBut happy either way.","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"}],"test/unit/cli/test_manage_shard_ranges.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"adebfa2ba0fedfa6274d679a5fed10c77bdbfdef","unresolved":false,"context_lines":[{"line_number":201,"context_line":"                    \u0027  \"cleaving_done\": false,\u0027,"},{"line_number":202,"context_line":"                    \u0027  \"cursor\": \"\",\u0027,"},{"line_number":203,"context_line":"                    \u0027  \"last_cleave_to_row\": null,\u0027,"},{"line_number":204,"context_line":"                    \u0027  \"last_modified\": null,\u0027,"},{"line_number":205,"context_line":"                    \u0027  \"max_row\": -1,\u0027,"},{"line_number":206,"context_line":"                    \u0027  \"misplaced_done\": false,\u0027,"},{"line_number":207,"context_line":"                    \u0027  \"ranges_done\": 0,\u0027,"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_d7563507","line":204,"updated":"2019-09-19 06:22:47.000000000","message":":-/\n\nWe should probably also have a case where this is populated... if nothing else, so we\u0027ll have an example of what it\u0027ll look like...","commit_id":"81a41da5420313f9cdb9c759bbb0f46c0d20c5af"}]}
