)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ff4da9b6c617ed4a0b9b873fc018356b43a27ed9","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"eaff8937_0ccbdc73","updated":"2024-08-19 14:38:43.000000000","message":"generally I like cli programs that operate on streams; but I think this tool should probably take the input file from a command line arg and take `-` as the arg to mean \"read from stdin\"\n\n926538: sq? pdb is no fun when stdin is closed | https://review.opendev.org/c/openstack/swift/+/926538\n\nI also think we should consider the graphviz dependency more carefully and maybe just break this out to a standalone tool linked off https://docs.openstack.org/swift/latest/associated_projects.html","commit_id":"f3256c8fc0c52306022d48a54acfac9046d3ed1e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b66ee58391abe7b6cfe906a7645318246a99fee7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"2805ee16_1774244e","updated":"2025-07-21 19:22:48.000000000","message":"I rebased this and it\u0027s still useful\n\nI expected it to work like `swift-graph-shardranges .scratch/root.db` sort of like `s-m-s-r` but I was able to get a json dump it was happy with using\n\n```\nswift-manage-shard-ranges /vagrant/.scratch/root.db show \u003e root.json\n```\n\nand then generate a pdf that was helpful with\n\n```\nvagrant@saio:/vagrant/.scratch$ time swift-graph-shardranges -a \u003c root.json \nRepairs necessary to remove overlapping shard ranges.\nChosen a complete sequence of 3278 shard ranges with current total of 3702040085 object records to accept object records from 145 overlapping donor shard ranges.\nOnce applied to the broker these changes will result in:\n    145 shard ranges being removed.\n    166399003 object records being moved to the chosen shard ranges.\nSaving file as there is no display\n\nreal\t0m8.828s\nuser\t0m8.110s\nsys\t0m0.337s\n```\n\nI solved for the dependency with `sudo apt-get install python3-graphviz`","commit_id":"afcf4b90b6ced0f954bad36a32d5dc19e7013323"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d514de03e26830dd9029f3edac49a6a3656ba510","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"17ecc40f_ae8f4bb6","updated":"2024-10-23 23:42:25.000000000","message":"It\u0027s a useful tool, will be a nice addition to land upstream. And I think the new introduction of library dependency is okay, as long as the tool itself quite gracefully and reminder users to install those library.\n\nput an ``-1`` because this patch lacks docstrings and some code refactoring will be nice.","commit_id":"afcf4b90b6ced0f954bad36a32d5dc19e7013323"}],"swift/cli/graph_shardranges.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d514de03e26830dd9029f3edac49a6a3656ba510","unresolved":true,"context_lines":[{"line_number":33,"context_line":"          \"graphviz tool\")"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""},{"line_number":36,"context_line":"def _cleanup_rec(rec):"},{"line_number":37,"context_line":"    for key, val in rec.items():"},{"line_number":38,"context_line":"        val \u003d val.strip()"},{"line_number":39,"context_line":"        if key in (\u0027lower:\u0027, \u0027Object Count:\u0027, \u0027Bytes Used:\u0027) and \\"}],"source_content_type":"text/x-python","patch_set":17,"id":"fe367b40_af0b77d5","line":36,"updated":"2024-10-23 23:42:25.000000000","message":"that\u0027ll be great to add docstring to explain what this function is used for.","commit_id":"afcf4b90b6ced0f954bad36a32d5dc19e7013323"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d514de03e26830dd9029f3edac49a6a3656ba510","unresolved":true,"context_lines":[{"line_number":92,"context_line":"    return shard_ranges"},{"line_number":93,"context_line":""},{"line_number":94,"context_line":""},{"line_number":95,"context_line":"def _info_bracket_data_to_data(ts):"},{"line_number":96,"context_line":"    if ts:"},{"line_number":97,"context_line":"        ts \u003d ts.split()"},{"line_number":98,"context_line":"        if len(ts) \u003d\u003d 2 and ts[-1].startswith(\u0027(\u0027):"}],"source_content_type":"text/x-python","patch_set":17,"id":"1ad22bfd_54e6a7c2","line":95,"updated":"2024-10-23 23:42:25.000000000","message":"ditto, please kindly add docstring to functions.","commit_id":"afcf4b90b6ced0f954bad36a32d5dc19e7013323"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d514de03e26830dd9029f3edac49a6a3656ba510","unresolved":true,"context_lines":[{"line_number":100,"context_line":"    return None"},{"line_number":101,"context_line":""},{"line_number":102,"context_line":""},{"line_number":103,"context_line":"def _from_json(args):"},{"line_number":104,"context_line":"    if args.json_input:"},{"line_number":105,"context_line":"        input_f \u003d open(args.json_input)"},{"line_number":106,"context_line":"    else:"}],"source_content_type":"text/x-python","patch_set":17,"id":"b8f60af6_b082880e","line":103,"updated":"2024-10-23 23:42:25.000000000","message":"use with statement like this?\n```    input_f \u003d open(args.json_input) if args.json_input else sys.stdin\n    with input_f:\n        try:\n            shard_ranges \u003d []\n            ranges \u003d json.load(input_f)\n            ...\n        except ValueError:\n            print(\u0027Failed to load json data\u0027)\n            return []```","commit_id":"afcf4b90b6ced0f954bad36a32d5dc19e7013323"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d514de03e26830dd9029f3edac49a6a3656ba510","unresolved":true,"context_lines":[{"line_number":184,"context_line":"    parser.add_argument("},{"line_number":185,"context_line":"        \u0027-a\u0027, \u0027--analyze\u0027, default\u003dFalse, action\u003d\u0027store_true\u0027,"},{"line_number":186,"context_line":"        help\u003d(\u0027Run ShardRanges through the analyzer and highlight the best \u0027"},{"line_number":187,"context_line":"              \u0027path\u0027))"},{"line_number":188,"context_line":"    parser.add_argument("},{"line_number":189,"context_line":"        \u0027-m\u0027, \u0027--min-shard-age\u0027, type\u003dint,"},{"line_number":190,"context_line":"        default\u003dMIN_SHARD_RANGE_AGE_FOR_REPAIR,"}],"source_content_type":"text/x-python","patch_set":17,"id":"990dd773_a7c421fa","line":187,"updated":"2024-10-23 23:42:25.000000000","message":"please add what\u0027s the best path, for sharding?","commit_id":"afcf4b90b6ced0f954bad36a32d5dc19e7013323"}],"swift/cli/shardrange_graph_viewer.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ff4da9b6c617ed4a0b9b873fc018356b43a27ed9","unresolved":true,"context_lines":[{"line_number":29,"context_line":"    from graphviz import Graph"},{"line_number":30,"context_line":"except ImportError:"},{"line_number":31,"context_line":"    Graph \u003d None"},{"line_number":32,"context_line":"    print(\"graphviz python module not installed.\")"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"def _cleanup_rec(rec):"}],"source_content_type":"text/x-python","patch_set":13,"id":"a8c26f9d_9e796798","line":32,"updated":"2024-08-19 14:38:43.000000000","message":"umm... should this *exit* too?","commit_id":"f3256c8fc0c52306022d48a54acfac9046d3ed1e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ff4da9b6c617ed4a0b9b873fc018356b43a27ed9","unresolved":true,"context_lines":[{"line_number":116,"context_line":"        return []"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"def _render_graph(graph, output, format):"},{"line_number":120,"context_line":"    try:"},{"line_number":121,"context_line":"        graph.render(\"{}/{}-{}.gv\".format(output, \"shard-ranges\","},{"line_number":122,"context_line":"                                          time.time()),"}],"source_content_type":"text/x-python","patch_set":13,"id":"e95dd6da_484e1d49","line":119,"updated":"2024-08-19 14:38:43.000000000","message":"the variable name format shadows a builtin\n\n```\n\u003e\u003e\u003e format\n\u003cbuilt-in function format\u003e\n```","commit_id":"f3256c8fc0c52306022d48a54acfac9046d3ed1e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"9b9dd0363028182ee71d17165663b40b835ae585","unresolved":false,"context_lines":[{"line_number":116,"context_line":"        return []"},{"line_number":117,"context_line":""},{"line_number":118,"context_line":""},{"line_number":119,"context_line":"def _render_graph(graph, output, format):"},{"line_number":120,"context_line":"    try:"},{"line_number":121,"context_line":"        graph.render(\"{}/{}-{}.gv\".format(output, \"shard-ranges\","},{"line_number":122,"context_line":"                                          time.time()),"}],"source_content_type":"text/x-python","patch_set":13,"id":"ab346f87_3ce8311c","line":119,"in_reply_to":"e95dd6da_484e1d49","updated":"2024-08-20 10:44:11.000000000","message":"Done","commit_id":"f3256c8fc0c52306022d48a54acfac9046d3ed1e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"ff4da9b6c617ed4a0b9b873fc018356b43a27ed9","unresolved":true,"context_lines":[{"line_number":122,"context_line":"                                          time.time()),"},{"line_number":123,"context_line":"                     view\u003dTrue, format\u003dformat)"},{"line_number":124,"context_line":"    except FileNotFoundError:"},{"line_number":125,"context_line":"        print(\u0027Saving file as there is no display\u0027)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"def make_graph(shard_ranges, graph_name, good_path\u003dNone):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7d63ec0a_b3943ff6","line":125,"updated":"2024-08-19 14:38:43.000000000","message":"pygraphviz is sort of a wierd \"binding\" for graphviz\n\n```\nTraceback (most recent call last):\n  File \"/usr/local/bin/swift-graph-shardranges\", line 10, in \u003cmodule\u003e\n    sys.exit(main())\n  File \"/vagrant/swift/swift/cli/shardrange_graph_viewer.py\", line 207, in main\n    _render_graph(graph, args.output, args.format)\n  File \"/vagrant/swift/swift/cli/shardrange_graph_viewer.py\", line 120, in _render_graph\n    graph.render(\"{}/{}-{}.gv\".format(output, \"shard-ranges\",\n  File \"/usr/local/lib/python3.10/dist-packages/graphviz/_tools.py\", line 171, in wrapper\n    return func(*args, **kwargs)\n  File \"/usr/local/lib/python3.10/dist-packages/graphviz/rendering.py\", line 122, in render\n    rendered \u003d self._render(*args, **kwargs)\n  File \"/usr/local/lib/python3.10/dist-packages/graphviz/_tools.py\", line 171, in wrapper\n    return func(*args, **kwargs)\n  File \"/usr/local/lib/python3.10/dist-packages/graphviz/backend/rendering.py\", line 326, in render\n    execute.run_check(cmd,\n  File \"/usr/local/lib/python3.10/dist-packages/graphviz/backend/execute.py\", line 81, in run_check\n    raise ExecutableNotFound(cmd) from e\ngraphviz.backend.execute.ExecutableNotFound: failed to execute PosixPath(\u0027dot\u0027), make sure the Graphviz executables are on your systems\u0027 PATH\n```\n\n```\n$ dot\nCommand \u0027dot\u0027 not found, but can be installed with:\napt install graphviz\nPlease ask your administrator.\n$ sudo apt install graphviz\n```","commit_id":"f3256c8fc0c52306022d48a54acfac9046d3ed1e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"9b9dd0363028182ee71d17165663b40b835ae585","unresolved":true,"context_lines":[{"line_number":122,"context_line":"                                          time.time()),"},{"line_number":123,"context_line":"                     view\u003dTrue, format\u003dformat)"},{"line_number":124,"context_line":"    except FileNotFoundError:"},{"line_number":125,"context_line":"        print(\u0027Saving file as there is no display\u0027)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"def make_graph(shard_ranges, graph_name, good_path\u003dNone):"}],"source_content_type":"text/x-python","patch_set":13,"id":"855801ad_e124119d","line":125,"in_reply_to":"040ff413_d0cf3d99","updated":"2024-08-20 10:44:11.000000000","message":"I worte this a few years ago, maybe there is a pure python graph visualiser I could use now. I\u0027ll have a quick look around.","commit_id":"f3256c8fc0c52306022d48a54acfac9046d3ed1e"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f1839f1eb9f674e47ad8458f07b079dfbe99b73a","unresolved":true,"context_lines":[{"line_number":122,"context_line":"                                          time.time()),"},{"line_number":123,"context_line":"                     view\u003dTrue, format\u003dformat)"},{"line_number":124,"context_line":"    except FileNotFoundError:"},{"line_number":125,"context_line":"        print(\u0027Saving file as there is no display\u0027)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"def make_graph(shard_ranges, graph_name, good_path\u003dNone):"}],"source_content_type":"text/x-python","patch_set":13,"id":"040ff413_d0cf3d99","line":125,"in_reply_to":"7d63ec0a_b3943ff6","updated":"2024-08-20 10:32:08.000000000","message":"yeah needs graphviz.. I did try and warn about needing it so relax the requirements.","commit_id":"f3256c8fc0c52306022d48a54acfac9046d3ed1e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"d514de03e26830dd9029f3edac49a6a3656ba510","unresolved":true,"context_lines":[{"line_number":122,"context_line":"                                          time.time()),"},{"line_number":123,"context_line":"                     view\u003dTrue, format\u003dformat)"},{"line_number":124,"context_line":"    except FileNotFoundError:"},{"line_number":125,"context_line":"        print(\u0027Saving file as there is no display\u0027)"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":""},{"line_number":128,"context_line":"def make_graph(shard_ranges, graph_name, good_path\u003dNone):"}],"source_content_type":"text/x-python","patch_set":13,"id":"7473596d_2ad606ae","line":125,"in_reply_to":"855801ad_e124119d","updated":"2024-10-23 23:42:25.000000000","message":"I saw people were saying that python has built-in turtle graphics, it could do the similar things we would need for this new tool, however I still needed to install ``python-tk`` in order to run an example.","commit_id":"f3256c8fc0c52306022d48a54acfac9046d3ed1e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"a3e997e3012bf37762501a7469552283e797a5dd","unresolved":true,"context_lines":[{"line_number":29,"context_line":"    from graphviz import Graph"},{"line_number":30,"context_line":"except ImportError:"},{"line_number":31,"context_line":"    Graph \u003d None"},{"line_number":32,"context_line":"    print(\"graphviz python module not installed. You might also need the \""},{"line_number":33,"context_line":"          \"graphviz tool\")"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"bc5159cc_45782c5a","line":32,"updated":"2024-10-23 00:36:32.000000000","message":"I feel it\u0027s okay if users have to install dependencies on their own to use this tool, as long as this tool peacefully exits and tells users that \"Please install graphviz using \u0027pip install graphviz\u0027, before you run this tool.\" something like that.\n\nThis tool is going to be very useful for upstream guys to debug sharding related issues.","commit_id":"61e412a51d9dd48c43b26f1b1dabb60e2177b81c"}]}
