)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"38e4da1f03c89fec7bed191d86d1499b7fabd5c2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"1a73840e_6183bd94","updated":"2022-05-10 00:35:13.000000000","message":"I think I managed to get a gap on my vsaio by commenting out the expand call in process_compactible_ranges\n\n(vagrant-swift-all-in-one) clayg@banana:~/Workspace/vagrant-swift-all-in-one/swift$ git diff\ndiff --git a/swift/container/sharder.py b/swift/container/sharder.py\nindex e933b7cb9..604e53e38 100644\n--- a/swift/container/sharder.py\n+++ b/swift/container/sharder.py\n@@ -334,10 +334,10 @@ def process_compactible_shard_sequences(broker, sequences):\n         # Update the acceptor container with its expanded bounds to prevent it\n         # treating objects cleaved from the donor as misplaced.\n         acceptor \u003d sequence[-1]\n-        if acceptor.expand(donors):\n-            # Update the acceptor container with its expanded bounds to prevent\n-            # it treating objects cleaved from the donor as misplaced.\n-            acceptor.timestamp \u003d timestamp\n+        # if acceptor.expand(donors):\n+        #     # Update the acceptor container with its expanded bounds to prevent\n+        #     # it treating objects cleaved from the donor as misplaced.\n+        #     acceptor.timestamp \u003d timestamp\n         if acceptor.update_state(ShardRange.ACTIVE):\n             # Ensure acceptor state is ACTIVE (when acceptor is root)\n             acceptor.state_timestamp \u003d timestamp\n\nIt looked like this:\n\nvagrant@saio:/vagrant/.scratch/nv-swift-gizmos/vsaio-tools$ swift-manage-shard-ranges /srv/node1/sdb1/containers/54/c48/dbb45b15fb6a3d12bd0e2c733a79cc48/dbb45b15fb6a3d12bd0e2c733a79cc48_1652136470.26760.db show\nLoaded db broker for AUTH_test/lots-of-files\nExisting shard ranges:\n[\n  {\n    \"bytes_used\": 0,\n    \"deleted\": 0,\n    \"epoch\": \"1652136971.06353\",\n    \"lower\": \"\",\n    \"meta_timestamp\": \"1652137008.16847\",\n    \"name\": \".shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1652136470.26425-1\",\n    \"object_count\": 200,\n    \"reported\": 0,\n    \"state\": \"shrinking\",\n    \"state_timestamp\": \"1652136971.06353\",\n    \"timestamp\": \"1652136842.81023\",\n    \"tombstones\": 0,\n    \"upper\": \"obj0199\"\n  },\n  {\n    \"bytes_used\": 0,\n    \"deleted\": 0,\n    \"epoch\": null,\n    \"lower\": \"obj0199\",\n    \"meta_timestamp\": \"1652136626.19034\",\n    \"name\": \".shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1652136470.26425-2\",\n    \"object_count\": 100,\n    \"reported\": 0,\n    \"state\": \"active\",\n    \"state_timestamp\": \"1652136470.26425\",\n    \"timestamp\": \"1652136470.26425\",\n    \"tombstones\": 0,\n    \"upper\": \"obj0299\"\n  },\n  {\n    \"bytes_used\": 0,\n    \"deleted\": 0,\n    \"epoch\": \"1652137479.52587\",\n    \"lower\": \"obj0299\",\n    \"meta_timestamp\": \"1652136638.21148\",\n    \"name\": \".shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1652136470.26425-3\",\n    \"object_count\": 100,\n    \"reported\": 0,\n    \"state\": \"shrinking\",\n    \"state_timestamp\": \"1652137479.52587\",\n    \"timestamp\": \"1652136470.26425\",\n    \"tombstones\": 0,\n    \"upper\": \"obj0399\"\n  },\n  {\n    \"bytes_used\": 0,\n    \"deleted\": 0,\n    \"epoch\": null,\n    \"lower\": \"obj0399\",\n    \"meta_timestamp\": \"1652136638.66548\",\n    \"name\": \".shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1652136470.26425-4\",\n    \"object_count\": 100,\n    \"reported\": 0,\n    \"state\": \"active\",\n    \"state_timestamp\": \"1652136470.26425\",\n    \"timestamp\": \"1652136470.26425\",\n    \"tombstones\": 0,\n    \"upper\": \"obj0499\"\n  },\n  {\n    \"bytes_used\": 0,\n    \"deleted\": 0,\n    \"epoch\": null,\n    \"lower\": \"obj0499\",\n    \"meta_timestamp\": \"1652136638.43959\",\n    \"name\": \".shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1652136470.26425-5\",\n    \"object_count\": 100,\n    \"reported\": 0,\n    \"state\": \"active\",\n    \"state_timestamp\": \"1652136470.26425\",\n    \"timestamp\": \"1652136470.26425\",\n    \"tombstones\": 0,\n    \"upper\": \"obj0599\"\n  },\n  {\n    \"bytes_used\": 0,\n    \"deleted\": 0,\n    \"epoch\": null,\n    \"lower\": \"obj0599\",\n    \"meta_timestamp\": \"1652136638.50659\",\n    \"name\": \".shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1652136470.26425-6\",\n    \"object_count\": 100,\n    \"reported\": 0,\n    \"state\": \"active\",\n    \"state_timestamp\": \"1652136470.26425\",\n    \"timestamp\": \"1652136470.26425\",\n    \"tombstones\": 0,\n    \"upper\": \"obj0699\"\n  },\n  {\n    \"bytes_used\": 0,\n    \"deleted\": 0,\n    \"epoch\": null,\n    \"lower\": \"obj0699\",\n    \"meta_timestamp\": \"1652136638.14791\",\n    \"name\": \".shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1652136470.26425-7\",\n    \"object_count\": 100,\n    \"reported\": 0,\n    \"state\": \"active\",\n    \"state_timestamp\": \"1652136470.26425\",\n    \"timestamp\": \"1652136470.26425\",\n    \"tombstones\": 0,\n    \"upper\": \"obj0799\"\n  },\n  {\n    \"bytes_used\": 0,\n    \"deleted\": 0,\n    \"epoch\": null,\n    \"lower\": \"obj0799\",\n    \"meta_timestamp\": \"1652136638.36973\",\n    \"name\": \".shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1652136470.26425-8\",\n    \"object_count\": 100,\n    \"reported\": 0,\n    \"state\": \"active\",\n    \"state_timestamp\": \"1652136470.26425\",\n    \"timestamp\": \"1652136470.26425\",\n    \"tombstones\": 0,\n    \"upper\": \"obj0899\"\n  },\n  {\n    \"bytes_used\": 0,\n    \"deleted\": 0,\n    \"epoch\": null,\n    \"lower\": \"obj0899\",\n    \"meta_timestamp\": \"1652136596.48030\",\n    \"name\": \".shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1652136470.26425-9\",\n    \"object_count\": 100,\n    \"reported\": 0,\n    \"state\": \"active\",\n    \"state_timestamp\": \"1652136470.26425\",\n    \"timestamp\": \"1652136470.26425\",\n    \"tombstones\": 0,\n    \"upper\": \"\"\n  }\n]\n\nBut the tool still blew up when I tried to repair --gaps\n\nvagrant@saio:/vagrant/.scratch/nv-swift-gizmos/vsaio-tools$ swift-manage-shard-ranges /srv/node1/sdb1/containers/54/c48/dbb45b15fb6a3d12bd0e2c733a79cc48/dbb45b15fb6a3d12bd0e2c733a79cc48_1652136470.26760.db repair --gaps\nLoaded db broker for AUTH_test/lots-of-files\nTraceback (most recent call last):\n  File \"/usr/local/bin/swift-manage-shard-ranges\", line 10, in \u003cmodule\u003e\n    sys.exit(main())\n  File \"/vagrant/swift/swift/cli/manage_shard_ranges.py\", line 1043, in main\n    return args.func(broker, args)\n  File \"/vagrant/swift/swift/cli/manage_shard_ranges.py\", line 750, in repair_shard_ranges\n    return repair_gaps(broker, args)\n  File \"/vagrant/swift/swift/cli/manage_shard_ranges.py\", line 616, in repair_gaps\n    start_path, end_path \u003d _find_gap(paths, start)\n  File \"/vagrant/swift/swift/cli/manage_shard_ranges.py\", line 602, in _find_gap\n    end_paths \u003d [path for path in paths if path.lower \u003e start_paths[-1].upper]\n  File \"/vagrant/swift/swift/cli/manage_shard_ranges.py\", line 602, in \u003clistcomp\u003e\n    end_paths \u003d [path for path in paths if path.lower \u003e start_paths[-1].upper]\nIndexError: list index out of range\n\nsorry I don\u0027t have more :\u0027(","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"91738c46c5ab474c9440d6875fd06901db82615f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"0cd84e21_9adc264e","updated":"2022-05-10 14:03:55.000000000","message":"matt\u0027s follow-up tests might be a good start at helping us produce a reasonable looking root with gaps that we can reapir.","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a7d09aa17028d5f0da33ee3198bb4fd7f5290b4e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"c638a1c9_0a82b25b","updated":"2022-05-11 01:26:46.000000000","message":"Nice! Love the use of null/start and null/end paths, genious! ","commit_id":"892e9200ef78bbe17d0a06d9d988aa67d0a53165"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"f51d7806_dbfabe66","updated":"2022-05-11 19:29:41.000000000","message":"Seems to make sense -- and the probe test looks like exactly the sort of situation we ran into.","commit_id":"ceb0995adc34b5707912af323d2cc766deeddb0e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6dd0c8a20329e43cf7b8c1f491b69cc1e9982741","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"e3048f2e_9928fd0d","updated":"2022-05-11 20:05:36.000000000","message":"Definitely still good for the immediate purpose.","commit_id":"35cd5f54e85f9757340fb32d121ebdf3ea701136"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7381ccf880d0f6b3061641be934ec0e9282a8ddf","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"21ef1504_02e13aea","updated":"2022-05-23 05:58:45.000000000","message":"Had some saved draft comments, just publishing them before anything else, they may not be of relevance now 😊","commit_id":"ae7dacac5cd17b48d523cc98a20d2fce813e51c9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed0635f3b017b30b41214146db7ea7932706bf4a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"6ccb44c9_e18d5e25","updated":"2022-05-19 18:21:37.000000000","message":"Refactored some of the new functions into sharder.py and replaced find_missing_ranges()\n\nAdded cautionary note to the command output re stopping auto-sharding.\n","commit_id":"ae7dacac5cd17b48d523cc98a20d2fce813e51c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3d3cb92c3befbfb9cdd1f9abc979beb7e879f5d8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"348d5905_38feb45f","updated":"2022-05-23 10:02:15.000000000","message":"Yup, looks good, and last patchset is only a function rename. We\u0027ve also have had to use this in prod to save our bacon.. So in anycase 1 millions times better then anything we have now!","commit_id":"b45b45fa729caa8c36f874658b69f92122dfbead"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fb6b83c0d69fc980cdd9800fa95765ceb869720a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"2de37a94_7db1601c","updated":"2022-05-31 17:52:45.000000000","message":"recheck\n\nCI failures should have been resolved by https://review.opendev.org/c/openstack/swift/+/842817","commit_id":"b45b45fa729caa8c36f874658b69f92122dfbead"}],"swift/cli/manage_shard_ranges.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"38e4da1f03c89fec7bed191d86d1499b7fabd5c2","unresolved":true,"context_lines":[{"line_number":601,"context_line":"    start_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":602,"context_line":"    end_paths \u003d [path for path in paths if path.lower \u003e start_paths[-1].upper]"},{"line_number":603,"context_line":"    end_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":604,"context_line":"    return start_paths[-1], end_paths[0] if end_paths else ShardRangeList()"},{"line_number":605,"context_line":""},{"line_number":606,"context_line":""},{"line_number":607,"context_line":"def repair_gaps(broker, args):"}],"source_content_type":"text/x-python","patch_set":2,"id":"ae993b8c_a215d698","line":604,"updated":"2022-05-10 00:35:13.000000000","message":"this blew up when i ran it on a shard with no gaps\n\n  vagrant@saio:/vagrant/.scratch/nv-swift-gizmos/vsaio-tools$ swift-manage-shard-ranges /srv/node3/sdb3/containers/28/611/7014ec0dc0062e35e34448e726cba611/7014ec0dc0062e35e34448e726cba611.db repair --gaps\n  Loaded db broker for .shards_AUTH_test/lots-of-files-9933d06bdb1de26a4adfa0a7692feae9-1652136470.26425-2\n  Traceback (most recent call last):\n    File \"/usr/local/bin/swift-manage-shard-ranges\", line 10, in \u003cmodule\u003e\n      sys.exit(main())\n    File \"/vagrant/swift/swift/cli/manage_shard_ranges.py\", line 1043, in main\n      return args.func(broker, args)\n    File \"/vagrant/swift/swift/cli/manage_shard_ranges.py\", line 750, in repair_shard_ranges\n      return repair_gaps(broker, args)\n    File \"/vagrant/swift/swift/cli/manage_shard_ranges.py\", line 616, in repair_gaps\n      start_path, end_path \u003d _find_gap(paths, start)\n    File \"/vagrant/swift/swift/cli/manage_shard_ranges.py\", line 604, in _find_gap\n      return start_paths[-1], end_paths[0] if end_paths else ShardRangeList()\n  IndexError: list index out of range","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"83db78f1cca60873784f873d3523775f2f5df0e5","unresolved":false,"context_lines":[{"line_number":601,"context_line":"    start_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":602,"context_line":"    end_paths \u003d [path for path in paths if path.lower \u003e start_paths[-1].upper]"},{"line_number":603,"context_line":"    end_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":604,"context_line":"    return start_paths[-1], end_paths[0] if end_paths else ShardRangeList()"},{"line_number":605,"context_line":""},{"line_number":606,"context_line":""},{"line_number":607,"context_line":"def repair_gaps(broker, args):"}],"source_content_type":"text/x-python","patch_set":2,"id":"03c3a988_65b5d959","line":604,"in_reply_to":"278e3fe8_7ea7a6f1","updated":"2022-05-11 21:10:49.000000000","message":"Done","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7a4fb5908c8889b262796370aac49ce001a9ff30","unresolved":true,"context_lines":[{"line_number":601,"context_line":"    start_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":602,"context_line":"    end_paths \u003d [path for path in paths if path.lower \u003e start_paths[-1].upper]"},{"line_number":603,"context_line":"    end_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":604,"context_line":"    return start_paths[-1], end_paths[0] if end_paths else ShardRangeList()"},{"line_number":605,"context_line":""},{"line_number":606,"context_line":""},{"line_number":607,"context_line":"def repair_gaps(broker, args):"}],"source_content_type":"text/x-python","patch_set":2,"id":"278e3fe8_7ea7a6f1","line":604,"in_reply_to":"ae993b8c_a215d698","updated":"2022-05-10 10:28:31.000000000","message":"It works fine on the a root container, and I\u0027m pretty sure, seeing and everything is root driven the root container is expected here not a shard... but having said that we should probably not stack trace but instead check and error.","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7a4fb5908c8889b262796370aac49ce001a9ff30","unresolved":true,"context_lines":[{"line_number":610,"context_line":"    # note: find_paths results do not include shrinking ranges"},{"line_number":611,"context_line":"    paths \u003d find_paths(shard_ranges)"},{"line_number":612,"context_line":"    paths_with_gaps \u003d []"},{"line_number":613,"context_line":"    # TODO: support case where no path starts at MIN"},{"line_number":614,"context_line":"    start \u003d ShardRange.MIN"},{"line_number":615,"context_line":"    while True:"},{"line_number":616,"context_line":"        start_path, end_path \u003d _find_gap(paths, start)"}],"source_content_type":"text/x-python","patch_set":2,"id":"c1b1d246_3e784a24","line":613,"updated":"2022-05-10 10:28:31.000000000","message":"Need to deal with gap at the end case too.","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"a7d09aa17028d5f0da33ee3198bb4fd7f5290b4e","unresolved":false,"context_lines":[{"line_number":610,"context_line":"    # note: find_paths results do not include shrinking ranges"},{"line_number":611,"context_line":"    paths \u003d find_paths(shard_ranges)"},{"line_number":612,"context_line":"    paths_with_gaps \u003d []"},{"line_number":613,"context_line":"    # TODO: support case where no path starts at MIN"},{"line_number":614,"context_line":"    start \u003d ShardRange.MIN"},{"line_number":615,"context_line":"    while True:"},{"line_number":616,"context_line":"        start_path, end_path \u003d _find_gap(paths, start)"}],"source_content_type":"text/x-python","patch_set":2,"id":"4ed1edee_b9d4fcaa","line":613,"in_reply_to":"c1b1d246_3e784a24","updated":"2022-05-11 01:26:46.000000000","message":"Done","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"91738c46c5ab474c9440d6875fd06901db82615f","unresolved":true,"context_lines":[{"line_number":636,"context_line":"            expanding_range \u003d end_path[0]"},{"line_number":637,"context_line":"            if expanding_range.state \u003d\u003d ShardRange.ACTIVE:"},{"line_number":638,"context_line":"                expanding_ranges.append(expanding_range)"},{"line_number":639,"context_line":"                expanding_range.expand([gap_range])"},{"line_number":640,"context_line":"                expanding_range.timestamp \u003d timestamp"},{"line_number":641,"context_line":"            else:"},{"line_number":642,"context_line":"                print(\u0027Warning: cannot fix gap with non-ACTIVE neighbor:\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"e0bb1d5d_405b5fe4","line":639,"updated":"2022-05-10 14:03:55.000000000","message":"it would be nice to capture the expanding range(s) current bounds and display which way it\u0027s expanding.","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"66aa5d9be4567e2d3dc88108945e8ab3492b73d7","unresolved":false,"context_lines":[{"line_number":636,"context_line":"            expanding_range \u003d end_path[0]"},{"line_number":637,"context_line":"            if expanding_range.state \u003d\u003d ShardRange.ACTIVE:"},{"line_number":638,"context_line":"                expanding_ranges.append(expanding_range)"},{"line_number":639,"context_line":"                expanding_range.expand([gap_range])"},{"line_number":640,"context_line":"                expanding_range.timestamp \u003d timestamp"},{"line_number":641,"context_line":"            else:"},{"line_number":642,"context_line":"                print(\u0027Warning: cannot fix gap with non-ACTIVE neighbor:\u0027)"}],"source_content_type":"text/x-python","patch_set":2,"id":"27b1fcf0_df62de7c","line":639,"in_reply_to":"e0bb1d5d_405b5fe4","updated":"2022-05-10 21:06:06.000000000","message":"Done","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"38e4da1f03c89fec7bed191d86d1499b7fabd5c2","unresolved":true,"context_lines":[{"line_number":714,"context_line":"    if not broker.is_root_container():"},{"line_number":715,"context_line":"        print(\u0027WARNING: Shard containers cannot be repaired.\u0027)"},{"line_number":716,"context_line":"        print(\u0027This command should be used on a root container.\u0027)"},{"line_number":717,"context_line":"        return EXIT_ERROR"},{"line_number":718,"context_line":""},{"line_number":719,"context_line":"    shard_ranges \u003d broker.get_shard_ranges()"},{"line_number":720,"context_line":"    if not shard_ranges:"}],"source_content_type":"text/x-python","patch_set":2,"id":"42c9b578_7bafc52d","line":717,"updated":"2022-05-10 00:35:13.000000000","message":"looks like we guard in repair_overlaps","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed0635f3b017b30b41214146db7ea7932706bf4a","unresolved":false,"context_lines":[{"line_number":714,"context_line":"    if not broker.is_root_container():"},{"line_number":715,"context_line":"        print(\u0027WARNING: Shard containers cannot be repaired.\u0027)"},{"line_number":716,"context_line":"        print(\u0027This command should be used on a root container.\u0027)"},{"line_number":717,"context_line":"        return EXIT_ERROR"},{"line_number":718,"context_line":""},{"line_number":719,"context_line":"    shard_ranges \u003d broker.get_shard_ranges()"},{"line_number":720,"context_line":"    if not shard_ranges:"}],"source_content_type":"text/x-python","patch_set":2,"id":"6cd19f37_dea0e772","line":717,"in_reply_to":"24cdd689_4f1e1dc3","updated":"2022-05-19 18:21:37.000000000","message":"Done","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7a4fb5908c8889b262796370aac49ce001a9ff30","unresolved":true,"context_lines":[{"line_number":714,"context_line":"    if not broker.is_root_container():"},{"line_number":715,"context_line":"        print(\u0027WARNING: Shard containers cannot be repaired.\u0027)"},{"line_number":716,"context_line":"        print(\u0027This command should be used on a root container.\u0027)"},{"line_number":717,"context_line":"        return EXIT_ERROR"},{"line_number":718,"context_line":""},{"line_number":719,"context_line":"    shard_ranges \u003d broker.get_shard_ranges()"},{"line_number":720,"context_line":"    if not shard_ranges:"}],"source_content_type":"text/x-python","patch_set":2,"id":"24cdd689_4f1e1dc3","line":717,"in_reply_to":"42c9b578_7bafc52d","updated":"2022-05-10 10:28:31.000000000","message":"So there is a guard here, but not in repair_gaps. So we should move this guard back down to the \"new\" repair_shard_ranges.","commit_id":"0a45bdf7f35a4c5128e02dec3faa47958ac09960"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":610,"context_line":"    # select the longest of those"},{"line_number":611,"context_line":"    end_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":612,"context_line":"    longest_end_path \u003d end_paths[-1] if end_paths else ShardRangeList()"},{"line_number":613,"context_line":"    return longest_start_path, longest_end_path"},{"line_number":614,"context_line":""},{"line_number":615,"context_line":""},{"line_number":616,"context_line":"def _fix_gaps(broker, args, paths_with_gaps):"}],"source_content_type":"text/x-python","patch_set":6,"id":"563ad31b_e5cf9215","line":613,"updated":"2022-05-11 19:29:41.000000000","message":"We can\u0027t use https://github.com/openstack/swift/blob/master/swift/container/sharder.py#L83 ? I guess we need the shard ranges that touch those bounds...","commit_id":"ceb0995adc34b5707912af323d2cc766deeddb0e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed0635f3b017b30b41214146db7ea7932706bf4a","unresolved":false,"context_lines":[{"line_number":610,"context_line":"    # select the longest of those"},{"line_number":611,"context_line":"    end_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":612,"context_line":"    longest_end_path \u003d end_paths[-1] if end_paths else ShardRangeList()"},{"line_number":613,"context_line":"    return longest_start_path, longest_end_path"},{"line_number":614,"context_line":""},{"line_number":615,"context_line":""},{"line_number":616,"context_line":"def _fix_gaps(broker, args, paths_with_gaps):"}],"source_content_type":"text/x-python","patch_set":6,"id":"768fd149_9efdfd8c","line":613,"in_reply_to":"563ad31b_e5cf9215","updated":"2022-05-19 18:21:37.000000000","message":"Done","commit_id":"ceb0995adc34b5707912af323d2cc766deeddb0e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":641,"context_line":"            print(\u0027    gap can be fixed by expanding neighbor range:\u0027)"},{"line_number":642,"context_line":"            _print_shard_range(expanding_range, 3)"},{"line_number":643,"context_line":"        else:"},{"line_number":644,"context_line":"            print(\u0027Warning: cannot fix gap: non-ACTIVE neighbors\u0027)"},{"line_number":645,"context_line":""},{"line_number":646,"context_line":"    if args.max_expanding \u003e\u003d 0:"},{"line_number":647,"context_line":"        solutions \u003d solutions[:args.max_expanding]"}],"source_content_type":"text/x-python","patch_set":6,"id":"e114c636_26268d6a","line":644,"updated":"2022-05-11 19:29:41.000000000","message":"Do we have any plans for how we could proceed in this case?","commit_id":"ceb0995adc34b5707912af323d2cc766deeddb0e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":681,"context_line":"    # that a start_path and end_path is always found even when there is a gap"},{"line_number":682,"context_line":"    # at the start or end of the namespace"},{"line_number":683,"context_line":"    null_start \u003d ShardRange(\u0027null/start\u0027, timestamp,"},{"line_number":684,"context_line":"                            ShardRange.MIN, ShardRange.MIN)"},{"line_number":685,"context_line":"    null_end \u003d ShardRange(\u0027null/end\u0027, timestamp,"},{"line_number":686,"context_line":"                          ShardRange.MAX, ShardRange.MAX)"},{"line_number":687,"context_line":"    paths.extend([ShardRangeList([null_start]), ShardRangeList([null_end])])"}],"source_content_type":"text/x-python","patch_set":6,"id":"1e770158_5ed9315d","line":684,"updated":"2022-05-11 19:29:41.000000000","message":"Interesting (to me) that we don\u0027t have a check that lower \u003c upper...","commit_id":"ceb0995adc34b5707912af323d2cc766deeddb0e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"6dd0c8a20329e43cf7b8c1f491b69cc1e9982741","unresolved":true,"context_lines":[{"line_number":683,"context_line":"    null_start \u003d ShardRange(\u0027null/start\u0027, timestamp,"},{"line_number":684,"context_line":"                            ShardRange.MIN, ShardRange.MIN)"},{"line_number":685,"context_line":"    null_end \u003d ShardRange(\u0027null/end\u0027, timestamp,"},{"line_number":686,"context_line":"                          ShardRange.MAX, ShardRange.MAX)"},{"line_number":687,"context_line":"    paths.extend([ShardRangeList([null_start]), ShardRangeList([null_end])])"},{"line_number":688,"context_line":"    paths_with_gaps \u003d []"},{"line_number":689,"context_line":"    start \u003d null_start.lower"}],"source_content_type":"text/x-python","patch_set":6,"id":"422e1861_f92df348","line":686,"updated":"2022-05-11 20:05:36.000000000","message":"Oh! What state do these get created with? Is there a risk that we try to expand this made-up shard to cover a gap at the end?","commit_id":"ceb0995adc34b5707912af323d2cc766deeddb0e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"83db78f1cca60873784f873d3523775f2f5df0e5","unresolved":true,"context_lines":[{"line_number":683,"context_line":"    null_start \u003d ShardRange(\u0027null/start\u0027, timestamp,"},{"line_number":684,"context_line":"                            ShardRange.MIN, ShardRange.MIN)"},{"line_number":685,"context_line":"    null_end \u003d ShardRange(\u0027null/end\u0027, timestamp,"},{"line_number":686,"context_line":"                          ShardRange.MAX, ShardRange.MAX)"},{"line_number":687,"context_line":"    paths.extend([ShardRangeList([null_start]), ShardRangeList([null_end])])"},{"line_number":688,"context_line":"    paths_with_gaps \u003d []"},{"line_number":689,"context_line":"    start \u003d null_start.lower"}],"source_content_type":"text/x-python","patch_set":6,"id":"f52c23f8_8d43031e","line":686,"in_reply_to":"422e1861_f92df348","updated":"2022-05-11 21:10:49.000000000","message":"default state is FOUND. The unit tests include a gap at end of the namespace which is filled by expanding from below.","commit_id":"ceb0995adc34b5707912af323d2cc766deeddb0e"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed0635f3b017b30b41214146db7ea7932706bf4a","unresolved":false,"context_lines":[{"line_number":683,"context_line":"    null_start \u003d ShardRange(\u0027null/start\u0027, timestamp,"},{"line_number":684,"context_line":"                            ShardRange.MIN, ShardRange.MIN)"},{"line_number":685,"context_line":"    null_end \u003d ShardRange(\u0027null/end\u0027, timestamp,"},{"line_number":686,"context_line":"                          ShardRange.MAX, ShardRange.MAX)"},{"line_number":687,"context_line":"    paths.extend([ShardRangeList([null_start]), ShardRangeList([null_end])])"},{"line_number":688,"context_line":"    paths_with_gaps \u003d []"},{"line_number":689,"context_line":"    start \u003d null_start.lower"}],"source_content_type":"text/x-python","patch_set":6,"id":"ef3f8b19_f2d0afb5","line":686,"in_reply_to":"f52c23f8_8d43031e","updated":"2022-05-19 18:21:37.000000000","message":"made state explicit","commit_id":"ceb0995adc34b5707912af323d2cc766deeddb0e"}],"swift/container/sharder.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ed0635f3b017b30b41214146db7ea7932706bf4a","unresolved":true,"context_lines":[{"line_number":143,"context_line":"        start \u003d end_path.lower"},{"line_number":144,"context_line":"        if start_path.upper \u003e end_path.lower:"},{"line_number":145,"context_line":"            # overlap"},{"line_number":146,"context_line":"            continue"},{"line_number":147,"context_line":"        gap_range \u003d ShardRange(\u0027gap/index_%06d\u0027 % len(paths_with_gaps),"},{"line_number":148,"context_line":"                               timestamp,"},{"line_number":149,"context_line":"                               lower\u003dstart_path.upper,"}],"source_content_type":"text/x-python","patch_set":8,"id":"bfe384d9_883517ad","line":146,"updated":"2022-05-19 18:21:37.000000000","message":"this condition ^^ is new vs last patchset","commit_id":"ae7dacac5cd17b48d523cc98a20d2fce813e51c9"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5eed57478c0b7e4a27985465cff4505ee4b324a0","unresolved":true,"context_lines":[{"line_number":143,"context_line":"        start \u003d end_path.lower"},{"line_number":144,"context_line":"        if start_path.upper \u003e end_path.lower:"},{"line_number":145,"context_line":"            # overlap"},{"line_number":146,"context_line":"            continue"},{"line_number":147,"context_line":"        gap_range \u003d ShardRange(\u0027gap/index_%06d\u0027 % len(paths_with_gaps),"},{"line_number":148,"context_line":"                               timestamp,"},{"line_number":149,"context_line":"                               lower\u003dstart_path.upper,"}],"source_content_type":"text/x-python","patch_set":8,"id":"0a52b541_bffb3a7c","line":146,"in_reply_to":"1bbb48d2_948c724f","updated":"2022-05-23 08:45:51.000000000","message":"I had meant to rename _find_gap as _find_discontinuity because it does now return pairs of paths that either overlap of have a gap. will fix","commit_id":"ae7dacac5cd17b48d523cc98a20d2fce813e51c9"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"032ce39628a9584baa8d2bef4a9871ce9c0805b9","unresolved":true,"context_lines":[{"line_number":143,"context_line":"        start \u003d end_path.lower"},{"line_number":144,"context_line":"        if start_path.upper \u003e end_path.lower:"},{"line_number":145,"context_line":"            # overlap"},{"line_number":146,"context_line":"            continue"},{"line_number":147,"context_line":"        gap_range \u003d ShardRange(\u0027gap/index_%06d\u0027 % len(paths_with_gaps),"},{"line_number":148,"context_line":"                               timestamp,"},{"line_number":149,"context_line":"                               lower\u003dstart_path.upper,"}],"source_content_type":"text/x-python","patch_set":8,"id":"1bbb48d2_948c724f","line":146,"in_reply_to":"bfe384d9_883517ad","updated":"2022-05-23 06:37:19.000000000","message":"OK so to get here, the end_path.lower is less then start_path.upper, but the end_path.upper is greater then start_path.upper (because the _find_gaps does the upper to upper check to be a valid end_path).. so the gap is actually fully containered and there isn\u0027t technically a gap, more of a overlap adjustment.\n\nJust continue as I hope the audit would have discovered the overlap?","commit_id":"ae7dacac5cd17b48d523cc98a20d2fce813e51c9"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fb6b83c0d69fc980cdd9800fa95765ceb869720a","unresolved":true,"context_lines":[{"line_number":84,"context_line":"    # select the path that reaches furthest from start into the namespace"},{"line_number":85,"context_line":"    start_paths \u003d [path for path in paths if path.lower \u003d\u003d start]"},{"line_number":86,"context_line":"    start_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":87,"context_line":"    longest_start_path \u003d start_paths[-1]"},{"line_number":88,"context_line":"    # search for paths that end further into the namespace (note: these must"},{"line_number":89,"context_line":"    # have a lower that differs from the start_path upper, otherwise they would"},{"line_number":90,"context_line":"    # be part of the start_path longer!)"}],"source_content_type":"text/x-python","patch_set":9,"id":"ad9fe9e8_50b1df17","line":87,"updated":"2022-05-31 17:52:45.000000000","message":"nit: Since we only care about the last one, may as well do\n\n longest_start_path \u003d max(start_paths, key\u003dlambda p: p.upper)","commit_id":"b45b45fa729caa8c36f874658b69f92122dfbead"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fb6b83c0d69fc980cdd9800fa95765ceb869720a","unresolved":true,"context_lines":[{"line_number":93,"context_line":"    if end_paths:"},{"line_number":94,"context_line":"        # select those that begin nearest the start of the namespace"},{"line_number":95,"context_line":"        end_paths.sort(key\u003dlambda p: p.lower)"},{"line_number":96,"context_line":"        end_paths \u003d [p for p in end_paths if p.lower \u003d\u003d end_paths[0].lower]"},{"line_number":97,"context_line":"        # select the longest of those"},{"line_number":98,"context_line":"        end_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":99,"context_line":"        longest_end_path \u003d end_paths[-1]"}],"source_content_type":"text/x-python","patch_set":9,"id":"86dc8d50_2b9e7518","line":96,"range":{"start_line":96,"start_character":56,"end_line":96,"end_character":74},"updated":"2022-05-31 17:52:45.000000000","message":"Right, so we can have\n\n end_paths[0].lower \u003e longest_start_path.upper\n\nnow -- it\u0027s \"just\" an overlap.","commit_id":"b45b45fa729caa8c36f874658b69f92122dfbead"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fb6b83c0d69fc980cdd9800fa95765ceb869720a","unresolved":true,"context_lines":[{"line_number":96,"context_line":"        end_paths \u003d [p for p in end_paths if p.lower \u003d\u003d end_paths[0].lower]"},{"line_number":97,"context_line":"        # select the longest of those"},{"line_number":98,"context_line":"        end_paths.sort(key\u003dlambda p: p.upper)"},{"line_number":99,"context_line":"        longest_end_path \u003d end_paths[-1]"},{"line_number":100,"context_line":"    else:"},{"line_number":101,"context_line":"        longest_end_path \u003d None"},{"line_number":102,"context_line":"    return longest_start_path, longest_end_path"}],"source_content_type":"text/x-python","patch_set":9,"id":"a3b46821_69c63868","line":99,"updated":"2022-05-31 17:52:45.000000000","message":"Similar to above, maybe better as\n\n next_closest_lower \u003d min(p.lower for p in end_paths)\n longest_end_path \u003d max(\n     (p for p in end_paths if p.lower \u003d\u003d next_closest_lower),\n     key\u003dlambda p: p.upper)\n\n? Or maybe that\u0027s getting too dense.","commit_id":"b45b45fa729caa8c36f874658b69f92122dfbead"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fb6b83c0d69fc980cdd9800fa95765ceb869720a","unresolved":true,"context_lines":[{"line_number":141,"context_line":"        start_path, end_path \u003d _find_discontinuity(paths, start)"},{"line_number":142,"context_line":"        if end_path is None:"},{"line_number":143,"context_line":"            # end of namespace reached"},{"line_number":144,"context_line":"            break"},{"line_number":145,"context_line":"        start \u003d end_path.lower"},{"line_number":146,"context_line":"        if start_path.upper \u003e end_path.lower:"},{"line_number":147,"context_line":"            # overlap"}],"source_content_type":"text/x-python","patch_set":9,"id":"f2402473_b030b634","line":144,"updated":"2022-05-31 17:52:45.000000000","message":"I feel like we could turn _find_discontinuity into a generator and avoid the `while True: ... break` awkwardness.","commit_id":"b45b45fa729caa8c36f874658b69f92122dfbead"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fb6b83c0d69fc980cdd9800fa95765ceb869720a","unresolved":true,"context_lines":[{"line_number":154,"context_line":"    return paths_with_gaps"},{"line_number":155,"context_line":""},{"line_number":156,"context_line":""},{"line_number":157,"context_line":"def find_overlapping_ranges(shard_ranges):"},{"line_number":158,"context_line":"    \"\"\""},{"line_number":159,"context_line":"    Find all pairs of overlapping ranges in the given list."},{"line_number":160,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"ed070112_d9c3e080","line":157,"updated":"2022-05-31 17:52:45.000000000","message":"I\u0027m starting to wonder if this should use _find_discontinuity() as well...","commit_id":"b45b45fa729caa8c36f874658b69f92122dfbead"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fb6b83c0d69fc980cdd9800fa95765ceb869720a","unresolved":true,"context_lines":[{"line_number":416,"context_line":"    for shard_range in shard_ranges:"},{"line_number":417,"context_line":"        if shard_range.state \u003d\u003d ShardRange.SHRINKING:"},{"line_number":418,"context_line":"            # shrinking shards are not a viable edge in any path"},{"line_number":419,"context_line":"            continue"},{"line_number":420,"context_line":"        node_successors[shard_range.lower].append(shard_range)"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":"    paths \u003d []"}],"source_content_type":"text/x-python","patch_set":9,"id":"9460bfa8_9beaa86e","line":419,"updated":"2022-05-31 17:52:45.000000000","message":"I wonder if we should have done this filtering up in the caller...","commit_id":"b45b45fa729caa8c36f874658b69f92122dfbead"}],"test/probe/test_sharder.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":3403,"context_line":"        # put an object into the second of the 2 sub-shards so that the shard"},{"line_number":3404,"context_line":"        # will update the root next time the sharder is run; do this before"},{"line_number":3405,"context_line":"        # restarting root node 0 so that the object update is definitely"},{"line_number":3406,"context_line":"        # redirected to a sub-shard by root node 1 or 2."},{"line_number":3407,"context_line":"        new_obj_name \u003d obj_names[0] + \u0027a\u0027"},{"line_number":3408,"context_line":"        self.put_objects([new_obj_name])"},{"line_number":3409,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"f6e22fdf_75191dc0","line":3406,"updated":"2022-05-11 19:29:41.000000000","message":"And since we haven\u0027t done any object operations since the POST to enable sharding, we know shard ranges aren\u0027t in cache.","commit_id":"3a3e90232dc2f9857d192b9980de36055789d836"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":3404,"context_line":"        # will update the root next time the sharder is run; do this before"},{"line_number":3405,"context_line":"        # restarting root node 0 so that the object update is definitely"},{"line_number":3406,"context_line":"        # redirected to a sub-shard by root node 1 or 2."},{"line_number":3407,"context_line":"        new_obj_name \u003d obj_names[0] + \u0027a\u0027"},{"line_number":3408,"context_line":"        self.put_objects([new_obj_name])"},{"line_number":3409,"context_line":""},{"line_number":3410,"context_line":"        # restart root node 0"}],"source_content_type":"text/x-python","patch_set":5,"id":"9116ec80_d139b021","line":3407,"updated":"2022-05-11 19:29:41.000000000","message":"Maybe better to do\n\n obj_names \u003d self._make_object_names(5)\n\nthen filter the initial put_objects()","commit_id":"3a3e90232dc2f9857d192b9980de36055789d836"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":3430,"context_line":"            self.assertEqual("},{"line_number":3431,"context_line":"                [(ShardRange.MIN, obj_names[0]),"},{"line_number":3432,"context_line":"                 (obj_names[0], obj_names[1]),"},{"line_number":3433,"context_line":"                 (ShardRange.MIN, obj_names[1]),  # note: sharded"},{"line_number":3434,"context_line":"                 (obj_names[1], ShardRange.MAX)],"},{"line_number":3435,"context_line":"                [(sr.lower, sr.upper)"},{"line_number":3436,"context_line":"                 for sr in broker.get_shard_ranges(include_deleted\u003dTrue)])"}],"source_content_type":"text/x-python","patch_set":5,"id":"fdecdce0_6eb83be8","line":3433,"range":{"start_line":3433,"start_character":52,"end_line":3433,"end_character":65},"updated":"2022-05-11 19:29:41.000000000","message":"We can make this more explicit:\n\n self.assertEqual([\n     (ShardRange.ACTIVE, 0, ShardRange.MIN, obj_names[0]),\n     (ShardRange.ACTIVE, 0, obj_names[0], obj_names[1]),\n     (ShardRange.SHARDED, 1, ShardRange.MIN, obj_names[1]),\n     (ShardRange.ACTIVE, 0, obj_names[1], ShardRange.MAX),\n ], [\n     (sr.state, sr.deleted, sr.lower, sr.upper)\n     for sr in broker.get_shard_ranges(include_deleted\u003dTrue)])","commit_id":"3a3e90232dc2f9857d192b9980de36055789d836"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":3441,"context_line":"        sub_shard_part, nodes \u003d self.get_part_and_node_numbers(sub_shard)"},{"line_number":3442,"context_line":"        # we want the sub-shard to update root node 0 but not the sharded"},{"line_number":3443,"context_line":"        # shard, but there is a small chance the two will be in same partition"},{"line_number":3444,"context_line":"        # TODO: how can we work around this?"},{"line_number":3445,"context_line":"        self.assertNotEqual(sub_shard_part, shard_part,"},{"line_number":3446,"context_line":"                            \u0027You were unlucky, try again\u0027)"},{"line_number":3447,"context_line":"        self.sharders_once(additional_args\u003d\u0027--partitions\u003d%s\u0027 % sub_shard_part)"}],"source_content_type":"text/x-python","patch_set":5,"id":"c9e43d74_e3e7797e","line":3444,"updated":"2022-05-11 19:29:41.000000000","message":"Typically, we\u0027d work around this with retries -- but that gets painful when there\u0027s so much setup required before determining that we got unlucky.\n\nGood news is that we have some retries built into CI -- so instead of ~0.4% chance (1/256), it\u0027s more like 0.0015% chance (1/65k). Probably OK to merge as-is?\n\nIf we\u0027re really worried about it, we could at least retry with the other shard -- though the repair may not go the same way...","commit_id":"3a3e90232dc2f9857d192b9980de36055789d836"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":3452,"context_line":"                          ShardRange.ACTIVE,"},{"line_number":3453,"context_line":"                          ShardRange.ACTIVE],"},{"line_number":3454,"context_line":"                         [sr.state for sr in root_brokers[0].get_shard_ranges("},{"line_number":3455,"context_line":"                             include_deleted\u003dTrue)])"},{"line_number":3456,"context_line":"        self.assertEqual("},{"line_number":3457,"context_line":"            [(ShardRange.MIN, obj_names[1]),"},{"line_number":3458,"context_line":"             (obj_names[0], obj_names[1]),  # note: overlap!"}],"source_content_type":"text/x-python","patch_set":5,"id":"74e9e17a_f9666e16","line":3455,"range":{"start_line":3455,"start_character":29,"end_line":3455,"end_character":49},"updated":"2022-05-11 19:29:41.000000000","message":"We keep passing this -- but none of these are deleted yet, are they? Except for the SHARDED entry in the other primaries.\n\nMaybe we should make assertions on\n\n [(sr.state, sr.deleted) for sr in ...]\n\n? Or even combine with the bounds-check below.","commit_id":"3a3e90232dc2f9857d192b9980de36055789d836"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":3462,"context_line":""},{"line_number":3463,"context_line":"        # we are allowed to fix the overlap..."},{"line_number":3464,"context_line":"        msg \u003d self.assert_subprocess_success(["},{"line_number":3465,"context_line":"            \u0027swift-manage-shard-ranges\u0027, root_0_db_file, \u0027repair\u0027, \u0027--yes\u0027])"},{"line_number":3466,"context_line":"        self.assertIn("},{"line_number":3467,"context_line":"            \u0027Repairs necessary to remove overlapping shard ranges.\u0027, msg)"},{"line_number":3468,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"a9d8ece5_be839f81","line":3465,"updated":"2022-05-11 19:29:41.000000000","message":"I need to refresh my memory about how we pick a path to preserve...","commit_id":"3a3e90232dc2f9857d192b9980de36055789d836"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":3468,"context_line":""},{"line_number":3469,"context_line":"        self.sharders_once()"},{"line_number":3470,"context_line":"        self.sharders_once()"},{"line_number":3471,"context_line":"        self.container_replicators.once()"},{"line_number":3472,"context_line":""},{"line_number":3473,"context_line":"        # boo :\u0027( ... we made gap"},{"line_number":3474,"context_line":"        msg \u003d self.assert_subprocess_success(["}],"source_content_type":"text/x-python","patch_set":5,"id":"5bec997f_2dec3db7","line":3471,"updated":"2022-05-11 19:29:41.000000000","message":"We ought to be able to make a reliable assertion about shard range states at this point.","commit_id":"3a3e90232dc2f9857d192b9980de36055789d836"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fb6b83c0d69fc980cdd9800fa95765ceb869720a","unresolved":false,"context_lines":[{"line_number":3468,"context_line":""},{"line_number":3469,"context_line":"        self.sharders_once()"},{"line_number":3470,"context_line":"        self.sharders_once()"},{"line_number":3471,"context_line":"        self.container_replicators.once()"},{"line_number":3472,"context_line":""},{"line_number":3473,"context_line":"        # boo :\u0027( ... we made gap"},{"line_number":3474,"context_line":"        msg \u003d self.assert_subprocess_success(["}],"source_content_type":"text/x-python","patch_set":5,"id":"06992d61_6faf8f7a","line":3471,"in_reply_to":"5bec997f_2dec3db7","updated":"2022-05-31 17:52:45.000000000","message":"Done","commit_id":"3a3e90232dc2f9857d192b9980de36055789d836"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"19c7546d6fc1677269703e6fca7646ddaee40c26","unresolved":true,"context_lines":[{"line_number":3477,"context_line":"        self.assertIn("},{"line_number":3478,"context_line":"            \u0027Repairs necessary to fill gaps.\u0027, msg)"},{"line_number":3479,"context_line":""},{"line_number":3480,"context_line":"        self.sharders_once()"},{"line_number":3481,"context_line":"        self.sharders_once()"},{"line_number":3482,"context_line":"        self.container_replicators.once()"},{"line_number":3483,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"f319f2b9_9338e4f9","line":3480,"updated":"2022-05-11 19:29:41.000000000","message":"I\u0027m a little surprised we don\u0027t need to run replicators first...","commit_id":"3a3e90232dc2f9857d192b9980de36055789d836"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7381ccf880d0f6b3061641be934ec0e9282a8ddf","unresolved":true,"context_lines":[{"line_number":3494,"context_line":"                 (ShardRange.ACTIVE, False, obj_names[0], ShardRange.MAX)],"},{"line_number":3495,"context_line":"                [(sr.state, sr.deleted, sr.lower, sr.upper)"},{"line_number":3496,"context_line":"                 for sr in broker.get_shard_ranges(include_deleted\u003dTrue)])"},{"line_number":3497,"context_line":""},{"line_number":3498,"context_line":"        msg \u003d self.assert_subprocess_success(["},{"line_number":3499,"context_line":"            \u0027swift-manage-shard-ranges\u0027, root_0_db_file, \u0027repair\u0027,"},{"line_number":3500,"context_line":"            \u0027--dry-run\u0027])"}],"source_content_type":"text/x-python","patch_set":7,"id":"27581001_9228c0ef","line":3497,"updated":"2022-05-23 05:58:45.000000000","message":"Can we grab the SHRUNK shard broker and confirm it has the expected acceptor in it? I mean it should, but a nice assert. I assume it should still be there, we don\u0027t remove clear the shards table on delete of the container.","commit_id":"35cd5f54e85f9757340fb32d121ebdf3ea701136"}],"test/unit/cli/test_manage_shard_ranges.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fb6b83c0d69fc980cdd9800fa95765ceb869720a","unresolved":true,"context_lines":[{"line_number":1841,"context_line":"             \u0027The following expanded shard range(s) will be applied to the \u0027"},{"line_number":1842,"context_line":"             \u0027DB:\u0027,"},{"line_number":1843,"context_line":"             \"    \u0027%s\u0027\" % orig_shard_ranges[3].name] +"},{"line_number":1844,"context_line":"            [mock.ANY] * 6 +"},{"line_number":1845,"context_line":"            [\u0027\u0027,"},{"line_number":1846,"context_line":"             \u0027Run container-replicator to replicate the changes to \u0027"},{"line_number":1847,"context_line":"             \u0027other nodes.\u0027,"}],"source_content_type":"text/x-python","patch_set":9,"id":"e7a18162_fc8ebe7b","line":1844,"updated":"2022-05-31 17:52:45.000000000","message":"\u0027K, +4 for the message from L1743-1749.","commit_id":"b45b45fa729caa8c36f874658b69f92122dfbead"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fb6b83c0d69fc980cdd9800fa95765ceb869720a","unresolved":true,"context_lines":[{"line_number":2001,"context_line":"        with mock_timestamp_now(next(self.ts_iter)) as ts_now, \\"},{"line_number":2002,"context_line":"                mock.patch(\u0027sys.stdout\u0027, out), \\"},{"line_number":2003,"context_line":"                mock.patch(\u0027sys.stderr\u0027, err):"},{"line_number":2004,"context_line":"            ret \u003d main([broker.db_file, \u0027repair\u0027, \u0027--gaps\u0027, \u0027--yes\u0027])"},{"line_number":2005,"context_line":"        self.assertEqual(0, ret)"},{"line_number":2006,"context_line":"        err_lines \u003d err.getvalue().split(\u0027\\n\u0027)"},{"line_number":2007,"context_line":"        self.assert_starts_with(err_lines[0], \u0027Loaded db broker for \u0027)"}],"source_content_type":"text/x-python","patch_set":9,"id":"3160330f_5e872894","line":2004,"updated":"2022-05-31 17:52:45.000000000","message":"And we *have* to repair in this order, right? If we try to repair the overlap first, it\u0027ll bomb out complaining about gaps, yeah?","commit_id":"b45b45fa729caa8c36f874658b69f92122dfbead"}]}
