)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1c4c6823d33c2e6f78d03395f7545f43d12e80b6","unresolved":true,"context_lines":[{"line_number":15,"context_line":"UpgradeImpact:"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"When you change this config option you should run the"},{"line_number":18,"context_line":"swift-expirer-rebalancer tool."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Change-Id: Ia82099289c350a97e6a7d89501b2135a45048366"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"0c698971_bf0347ab","line":18,"range":{"start_line":18,"start_character":0,"end_line":18,"end_character":24},"updated":"2024-10-28 13:32:16.000000000","message":"this needs to be defined in the ``console_scripts`` in setup.cfg","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b85c9d374e62915a3b8d023ef0e463df5fb923b","unresolved":false,"context_lines":[{"line_number":15,"context_line":"UpgradeImpact:"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"When you change this config option you should run the"},{"line_number":18,"context_line":"swift-expirer-rebalancer tool."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Change-Id: Ia82099289c350a97e6a7d89501b2135a45048366"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"ee4e3c76_73318428","line":18,"range":{"start_line":18,"start_character":0,"end_line":18,"end_character":24},"in_reply_to":"0c698971_bf0347ab","updated":"2024-10-28 23:05:15.000000000","message":"Done","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5f3cef50aec56551b2d628014246612b77d1eaa1","unresolved":true,"context_lines":[{"line_number":15,"context_line":"UpgradeImpact:"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"When you change this config option you should run the"},{"line_number":18,"context_line":"swift-expirer-rebalancer tool."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Change-Id: Ia82099289c350a97e6a7d89501b2135a45048366"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"713a252d_5d745746","line":18,"updated":"2024-10-31 19:19:33.000000000","message":"Do we have any docs on this? Recommended concurrency settings, estimates of run-time, anything?","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"914f404eb803d9bb5c5a96f7c353024b2e809f10","unresolved":false,"context_lines":[{"line_number":15,"context_line":"UpgradeImpact:"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"When you change this config option you should run the"},{"line_number":18,"context_line":"swift-expirer-rebalancer tool."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Change-Id: Ia82099289c350a97e6a7d89501b2135a45048366"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"e3839099_a527e903","line":18,"in_reply_to":"448cfe2d_a24e80e5","updated":"2024-11-18 19:08:42.000000000","message":"i added some stub docs!  happy to have feedback on how to make them more useful, or maybe how to improve the tool/ux?","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":true,"context_lines":[{"line_number":15,"context_line":"UpgradeImpact:"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"When you change this config option you should run the"},{"line_number":18,"context_line":"swift-expirer-rebalancer tool."},{"line_number":19,"context_line":""},{"line_number":20,"context_line":"Change-Id: Ia82099289c350a97e6a7d89501b2135a45048366"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":3,"id":"448cfe2d_a24e80e5","line":18,"in_reply_to":"713a252d_5d745746","updated":"2024-11-05 00:23:25.000000000","message":"no, it\u0027s a new and still experimental tool - the upstream version isn\u0027t even the same code that we used to manage our migration - we\u0027ve just got what\u0027s in this patch.\n\nIt might be reasonable to say \"you shouldn\u0027t be able to configure your task_container_per_day w/o docs on how to use swift-expirer-rebalancer\" - probably could add a new section at the end of `overview_expiring_objects.rst`","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1c4c6823d33c2e6f78d03395f7545f43d12e80b6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"37100669_5f9ac415","updated":"2024-10-28 13:32:16.000000000","message":"Some suggestions here:\nhttps://paste.openstack.org/show/bfJUT0HjTORdjHjRvPfe/\n\nI didn\u0027t get too far with reviewing this patchset. I\u0027m guessing it\u0027s still WIP, but I\u0027m curious how expirerer_rebalance ran in prod cos it blows up for me...\n\n```\nvagrant@vagrant:~/swift$ python swift/cli/expirer_rebalance.py /etc/swift/object-expirer.conf.d/\nTraceback (most recent call last):\n  File \"swift/cli/expirer_rebalance.py\", line 346, in \u003cmodule\u003e\n    sys.exit(main())\n  File \"swift/cli/expirer_rebalance.py\", line 304, in main\n    args \u003d parse_args()\n  File \"swift/cli/expirer_rebalance.py\", line 290, in parse_args\n    set_verbosity_level(args.verbose, logger)\n  File \"swift/cli/expirer_rebalance.py\", line 223, in set_verbosity_level\n    logger.setLevel(verbose_map.get(verbose_count, logging.DEBUG))\nAttributeError: \u0027NoneType\u0027 object has no attribute \u0027setLevel\u0027\n```","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b85c9d374e62915a3b8d023ef0e463df5fb923b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"4522cdb3_4abbd511","updated":"2024-10-28 23:05:15.000000000","message":"probably some more refactoring and tests over the new expirer-rebalancer tool will be useful.","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b85c9d374e62915a3b8d023ef0e463df5fb923b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"d78db4b0_f3f0b093","in_reply_to":"37100669_5f9ac415","updated":"2024-10-28 23:05:15.000000000","message":"the version we ran in prod was different from this one.  Notably I changed the logging to go to swift\u0027s syslog instead of a bunch of per-worker files.","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"099729f292c9fe178eb06982cb935efd22f5f740","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"c80dd0b8_8e54025f","updated":"2024-10-30 14:09:51.000000000","message":"hrm.. i was only able to duplicate a couple of these failures with `cd /etc; sudo mv swift/ swift.bak`\n\n```\nFAILED swift/test/unit/cli/test_expirer_rebalancer.py::TestExpirerRebalance::test_main - FileNotFoundError: [Errno 2] No such file or directory: \u0027/etc/swift/internal-client.conf\u0027\nFAILED swift/test/unit/cli/test_expirer_rebalancer.py::TestExpirerRebalance::test_process_task_containers_errors - AssertionError: {\u0027processed_tasks\u0027: 25, \u0027success_tasks\u0027: 25} !\u003d {\u0027processed_tasks\u0027: 23, \u0027success_tasks\u0027: 23}\n```\n\nZuul has one assertion error like this:\n\n```\nE       AssertionError: Lists differ: [\u0027exp[40 chars]cated\u0027, \u0027expiring_objects_account_name is depr[66 chars]unt\u0027] !\u003d [\u0027exp[40 chars]cated; use expiring_objects_task_container_per[119 chars]unt\u0027]\nE       \nE       First differing element 0:\nE       \u0027expi[35 chars]eprecated\u0027\nE       \u0027expi[35 chars]eprecated; use expiring_objects_task_container_per_day instead\u0027\nE       \nE       - [\u0027expiring_objects_container_divisor is deprecated\u0027,\nE       ?                                                    -\nE       \nE       + [\u0027expiring_objects_container_divisor is deprecated; use \u0027\nE       ?                                                   ++++++\nE       \nE       +  \u0027expiring_objects_task_container_per_day instead\u0027,\nE          \u0027expiring_objects_account_name is deprecated; you need to migrate to the \u0027\nE          \u0027standard .expiring_objects account\u0027]\n\n```","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"da7d3eec27a25857d2c93410b30f30ee3fd7da38","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"1203f52c_57de7ca5","in_reply_to":"c80dd0b8_8e54025f","updated":"2024-10-30 14:11:22.000000000","message":"oic, the failure was in `proxy.test_server` should be fixable.","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2b6600ba12fe57889fdfcc11ca0a784906cab07a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"8a242529_0d3a2638","updated":"2024-11-04 00:44:11.000000000","message":"A few test failures, I am getting them fixed, will upload soon.","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"281381d987650152c84d7e3720d36bd6a7149795","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"02ac3216_d4eeceeb","updated":"2024-11-01 21:50:06.000000000","message":"I think the new cli tool is going to need a few more iterations; but the code we\u0027re relying on to configure `expiring_objects_task_container_per_day` all looks the same.","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0af0690936ef16c69504b67ee1f4e7b13531c4e5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"d542a43b_3b6d3af2","updated":"2024-11-04 10:55:22.000000000","message":"I think I eventually understood why the tests are intermittently failing. This is my first contact with these tests and I\u0027m not yet sure of the best solution: \n\n- make loading the tasks into containers more deterministic, e.g. for each task calculate the right container and then choose a different one\n\n- or make the assertions less hard-coded i.e. analyse the containers in the test to calculate how many tasks are actually wrongly placed.","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"fe2e623c_55b18cfc","updated":"2024-11-05 00:23:25.000000000","message":"the expirer-rebalancer should probably have some more tests/docs - but the guts of the configuration is mostly trivial with the ExpirerConfig refactor out of the way; we need to carry this to keep prod working.","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c979f91820b58b2fe47c5750c9699d9f47ae0260","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"5543bd8d_b5282289","updated":"2024-11-05 11:37:43.000000000","message":"Some fixups for the tests issues here https://review.opendev.org/c/openstack/swift/+/934117\n\nI still can\u0027t claim to have fully reviewed the rebalancer, but the expirer changes looks fine - same as we\u0027ve been carrying and using for a while.","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f2ce2cd613e51020c5250a5af03abd0679bda3f7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"ebacd307_f6eb28a2","updated":"2024-11-05 11:41:34.000000000","message":"clarifying my previous comment - I didn\u0027t get as far as fixing *all* the test issues in my follow-up","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0c708f029f396d55c07ffb2ab3e6bb80629ddf6e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"0fb64947_790d4809","updated":"2024-11-05 15:41:01.000000000","message":"thanks for the fixups!","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"44eb8d872e023d3b4bb8d811e698c6debf78fd5c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"de5cb067_44f879d2","updated":"2024-11-05 22:51:12.000000000","message":"this was a rushed squash; could probably use another pass","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"e0588eee424dbdbbf94621a2f40c29a392f365ee","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"bd5c626e_597a61f3","updated":"2024-11-05 23:33:11.000000000","message":"Looks like it\u0027s failing on py36 probably with the same thing Clay:\n\n```\n\u003e       ]}, self.logger.all_log_lines())\nE       AssertionError: {\u0027info\u0027: [\u0027skipping task_container 1730764[283 chars]ks\u0027]} !\u003d {}\nE       + {}\nE       - {\u0027info\u0027: [\u0027skipping task_container 1730764719 due in -1 days with 1 tasks\u0027,\nE       -           \u0027found task_container 1730851108 due in 0 days with 1 tasks\u0027,\nE       -           \u0027found task_container 1730851121 due in 0 days with 1 tasks\u0027,\nE       -           \u0027found task_container 1730851195 due in 0 days with 1 tasks\u0027,\nE       -           \u0027stopping at task_container 1730937591 due in 1 days with 1 tasks\u0027]}\n```\n\nWe probably need to do the logger.logger trick with 36 as well is my guess.","commit_id":"be09569733934165fa6b42705c2ffc1ba1d87bad"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"f1a26f777fd5a942c69534c5d391f1300f7fb606","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"f64e222e_1e8e08bc","updated":"2024-11-05 23:40:19.000000000","message":"maybe something like: https://paste.openstack.org/show/826019/\nTho that\u0027s pretty horrible.","commit_id":"be09569733934165fa6b42705c2ffc1ba1d87bad"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"cf95aadd9cb576b42815b12b0047740c0f9bc09c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"a59b6105_db3fb33d","updated":"2024-11-05 23:41:24.000000000","message":"maybe we can just make py36 non-voting :P","commit_id":"be09569733934165fa6b42705c2ffc1ba1d87bad"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"5e70ed22d91a02689adad21e648f51cddfb24cd0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"9012a152_9052c02f","updated":"2024-11-06 04:17:27.000000000","message":"Finally tracked down the py36 issue. step 1 was getting a py36 env up again :P\n\nSeems the weird verbosity stuff gets in the way of the debug_logger in python 3.6. py2 and the other py3 versions are fine attempting to write the logs even when the `logger.setLevel()` isn\u0027t called for INFO or DEBUG. But python36 will not pass it onto the debug adapter logger, unless it is set.\nWay around it so long as we are supporting py36 is to pass in `-vvv` as args so DEBUG level is set in any test where you want to use the rebalancer _and_ change log lines.","commit_id":"2a3f16893d294566d5952378d8994b95c8e71836"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4fabe76069f99f25ce2eb94828f4b57955ec9f5c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"1a4c71ec_69164882","updated":"2024-11-06 05:52:20.000000000","message":"yay its passing","commit_id":"2a3f16893d294566d5952378d8994b95c8e71836"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"6aca0856dd3eaa679b5b84f04497cec7d628de19","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"e98b8163_414b75d1","updated":"2024-11-15 06:04:14.000000000","message":"I like the new expirer rebalancer, it defines several classes and have them well-organized. BaseRebalancer, RebalancerWorker, ExpirerRebalancer, each class has a specific purpose, which helps a lot in maintainability.\n\nAnd I have tested this newer version tool on a test cluster, dry-run and the actual work mode all worked well. There could be some small improvement for the log messages, for example, the log messages for the dry-run mode almost had no difference to the actual work mode. But this patch itself is in a very good shape to introduce a new tool to swift/cli.","commit_id":"b6cf33b5d01006b308c81e4516e797fb1828d8f3"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"3b9a1fafdcc4e6c12402c8f7a7943b666862300f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"57d275ce_9507cad1","updated":"2024-11-15 18:54:23.000000000","message":"Fixed typos and improved rebalancer user guide a little bit.","commit_id":"d42d9c438de8a2d19b528a59c211fced2ebaf8d1"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e48a6628f70b80a7d6fe710b6cbd8923542a9be2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"33d21e3d_e3fa47ec","updated":"2024-11-18 11:22:37.000000000","message":"We\u0027ll need to rebase this on the fix for the duplicate prefix logging https://review.opendev.org/c/openstack/swift/+/935501","commit_id":"958848719b8b1b3587431a4698474675eedb5f4d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"914f404eb803d9bb5c5a96f7c353024b2e809f10","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":11,"id":"54e8b8fa_fa5a64b3","updated":"2024-11-18 19:08:42.000000000","message":"still a couple of issues I\u0027m leaving unaddressed this pass.  they may not be \"blockers\" if we want to enable this feature - but for ergonomics and robustness perhaps worth addressing before merge (if we can come up with the code/tests to fix them!)","commit_id":"958848719b8b1b3587431a4698474675eedb5f4d"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":16,"id":"91924f35_aa39ba3f","updated":"2025-02-07 23:05:28.000000000","message":"I\u0027d love to see some tests with non-ascii names, maybe a probe test to show the new tool in action.","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"fc49a442_f0d19a4c","updated":"2025-02-11 03:32:52.000000000","message":"will add one more test to move deletion tasks which point to objects with non-ascii names","commit_id":"343e8bb33cc7d8787d62052f94873e68bb3db5ae"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3ef589f6fb09a325d1e12aa321ab27ed1ea80ad","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":19,"id":"6cc41008_99f489b4","updated":"2025-02-12 00:59:49.000000000","message":"Thanks for the reviews!","commit_id":"09fb235eda7bf70a642856137c6a9009fa0c0055"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2b20e46fb23e6c76910b5ddfc7e2fd25da1569ab","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":20,"id":"a8d60797_6fbe8a86","updated":"2025-04-11 09:54:12.000000000","message":"I noticed a flakey test while rebasing this to fix the ``import mock``","commit_id":"3df47bbc917b2464b6ad2c05632945ce4e4a5037"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"d707cc0a16190ace541d5d258a73d2aa6258fc31","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":21,"id":"66a29744_5548cce9","updated":"2025-04-11 09:55:20.000000000","message":"see comment on patchset 20","commit_id":"9f71e9620f791716da923222f6379fbf0ade88b2"}],"doc/source/config/object_server_config.rst":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"281381d987650152c84d7e3720d36bd6a7149795","unresolved":true,"context_lines":[{"line_number":170,"context_line":"                                                     priority of the process. Work only with"},{"line_number":171,"context_line":"                                                     ionice_class."},{"line_number":172,"context_line":"                                                     Ignored if IOPRIO_CLASS_IDLE is set."},{"line_number":173,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":".. _object-server-options:"},{"line_number":176,"context_line":""}],"source_content_type":"text/x-rst","patch_set":4,"id":"a8dc00ab_9ea5da80","line":173,"updated":"2024-11-01 21:50:06.000000000","message":"oh yuk, so THIS section doesn\u0027t get reformatted in the deprecate change because the object-server didn\u0027t used to know/care about the expirer configuration - and now we add some logging...","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":170,"context_line":"                                                     priority of the process. Work only with"},{"line_number":171,"context_line":"                                                     ionice_class."},{"line_number":172,"context_line":"                                                     Ignored if IOPRIO_CLASS_IDLE is set."},{"line_number":173,"context_line":"\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d  \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d"},{"line_number":174,"context_line":""},{"line_number":175,"context_line":".. _object-server-options:"},{"line_number":176,"context_line":""}],"source_content_type":"text/x-rst","patch_set":4,"id":"fdfa5a77_79a9d8cc","line":173,"in_reply_to":"a8dc00ab_9ea5da80","updated":"2024-11-05 00:23:25.000000000","message":"Done","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"}],"doc/source/overview_expiring_objects.rst":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":136,"context_line":"As expiring objects are added to the system, the object servers will record the"},{"line_number":137,"context_line":"expirations in a hidden ``.expiring_objects`` account for the"},{"line_number":138,"context_line":"``swift-object-expirer`` to handle later.  The records inserted into the"},{"line_number":139,"context_line":"\"task_containers\" of the ``.expiring_objects`` account are not natively"},{"line_number":140,"context_line":"sharded; instead each day\u0027s worth of delete tasks are hashed into a"},{"line_number":141,"context_line":"configurable number of \"task_containers\" (100 by default)."},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"When the number of expiration tasks per day grows larger than 100 times the"}],"source_content_type":"text/x-rst","patch_set":16,"id":"81f044b8_d3f53a94","line":140,"range":{"start_line":139,"start_character":63,"end_line":140,"end_character":7},"updated":"2025-02-07 23:05:28.000000000","message":"Maybe have this link to the sharding docs, to make it clear what\u0027s meant by \"natively sharded\"?","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":136,"context_line":"As expiring objects are added to the system, the object servers will record the"},{"line_number":137,"context_line":"expirations in a hidden ``.expiring_objects`` account for the"},{"line_number":138,"context_line":"``swift-object-expirer`` to handle later.  The records inserted into the"},{"line_number":139,"context_line":"\"task_containers\" of the ``.expiring_objects`` account are not natively"},{"line_number":140,"context_line":"sharded; instead each day\u0027s worth of delete tasks are hashed into a"},{"line_number":141,"context_line":"configurable number of \"task_containers\" (100 by default)."},{"line_number":142,"context_line":""},{"line_number":143,"context_line":"When the number of expiration tasks per day grows larger than 100 times the"}],"source_content_type":"text/x-rst","patch_set":16,"id":"cc4037f8_85266a1a","line":140,"range":{"start_line":139,"start_character":63,"end_line":140,"end_character":7},"in_reply_to":"81f044b8_d3f53a94","updated":"2025-02-11 03:32:52.000000000","message":"``sharded`` here is kind of confusing, as it is related to ``container sharding`` but how to distributed all records into all containers. I have reworded it.","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":151,"context_line":"task_container\".  While these expirations will continue to be processed as"},{"line_number":152,"context_line":"normal, if any referenced object has its ``x-delete-at`` timestamp updated the"},{"line_number":153,"context_line":"\"stale task cleanup\" will target the wrong \"task_container\" which will leave"},{"line_number":154,"context_line":"the mishomed stale tasks in the queue."},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"You can avoid this inefficiency by using the ``swift-expirer-rebalancer`` CLI"},{"line_number":157,"context_line":"tool.  It can be run on any single node  with access to rings, configs and"}],"source_content_type":"text/x-rst","patch_set":16,"id":"25bbabcc_01b11b35","line":154,"range":{"start_line":154,"start_character":4,"end_line":154,"end_character":12},"updated":"2025-02-07 23:05:28.000000000","message":"That can\u0027t be a word. Maybe \"misfiled\" would be better? Here and below.","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":151,"context_line":"task_container\".  While these expirations will continue to be processed as"},{"line_number":152,"context_line":"normal, if any referenced object has its ``x-delete-at`` timestamp updated the"},{"line_number":153,"context_line":"\"stale task cleanup\" will target the wrong \"task_container\" which will leave"},{"line_number":154,"context_line":"the mishomed stale tasks in the queue."},{"line_number":155,"context_line":""},{"line_number":156,"context_line":"You can avoid this inefficiency by using the ``swift-expirer-rebalancer`` CLI"},{"line_number":157,"context_line":"tool.  It can be run on any single node  with access to rings, configs and"}],"source_content_type":"text/x-rst","patch_set":16,"id":"7bd1ec34_73855a7a","line":154,"range":{"start_line":154,"start_character":4,"end_line":154,"end_character":12},"in_reply_to":"25bbabcc_01b11b35","updated":"2025-02-11 03:32:52.000000000","message":"I replaced it with ``misplaced``.","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":158,"context_line":"container-servers in order to create a copy of the mishomed tasks in the"},{"line_number":159,"context_line":"\"correct task_container\" and then delete the mishomed tasks."},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"By default the tool runs on only the \"next days\" worth of task_containers, this"},{"line_number":162,"context_line":"works well to help ops estimate the runtime to process the entire queue. You\u0027ll"},{"line_number":163,"context_line":"need to run the ``swift-expirer-rebalancer`` multiple times with increasing"},{"line_number":164,"context_line":"values for ``--num-days`` in order to process the entire expirer queue. You can"}],"source_content_type":"text/x-rst","patch_set":16,"id":"b9226a13_38f066cb","line":161,"range":{"start_line":161,"start_character":58,"end_line":161,"end_character":79},"updated":"2025-02-07 23:05:28.000000000","message":"\u003e task_containers. This","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":158,"context_line":"container-servers in order to create a copy of the mishomed tasks in the"},{"line_number":159,"context_line":"\"correct task_container\" and then delete the mishomed tasks."},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"By default the tool runs on only the \"next days\" worth of task_containers, this"},{"line_number":162,"context_line":"works well to help ops estimate the runtime to process the entire queue. You\u0027ll"},{"line_number":163,"context_line":"need to run the ``swift-expirer-rebalancer`` multiple times with increasing"},{"line_number":164,"context_line":"values for ``--num-days`` in order to process the entire expirer queue. You can"}],"source_content_type":"text/x-rst","patch_set":16,"id":"47673939_c4bbb829","line":161,"range":{"start_line":161,"start_character":58,"end_line":161,"end_character":79},"in_reply_to":"b9226a13_38f066cb","updated":"2025-02-11 03:32:52.000000000","message":"Done","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":159,"context_line":"\"correct task_container\" and then delete the mishomed tasks."},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"By default the tool runs on only the \"next days\" worth of task_containers, this"},{"line_number":162,"context_line":"works well to help ops estimate the runtime to process the entire queue. You\u0027ll"},{"line_number":163,"context_line":"need to run the ``swift-expirer-rebalancer`` multiple times with increasing"},{"line_number":164,"context_line":"values for ``--num-days`` in order to process the entire expirer queue. You can"},{"line_number":165,"context_line":"use the ``--start-day-offset`` to avoid re-evaluating sections of the"}],"source_content_type":"text/x-rst","patch_set":16,"id":"88b9ca11_d4458b0e","line":162,"range":{"start_line":162,"start_character":14,"end_line":162,"end_character":71},"updated":"2025-02-07 23:05:28.000000000","message":"Do we have any upstream tooling to estimate the size of the expiry queue? This reminds me of a homework question that infuriated my daughter:\n\n\u003e Jimmy has 36 apples to distribute evenly into bags. How many apples will be in each bag?\n\nGreat, we\u0027ve got a number -- but *what\u0027s the other number?*\n\nWe should go revisit https://review.opendev.org/c/openstack/swift/+/893861","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":true,"context_lines":[{"line_number":159,"context_line":"\"correct task_container\" and then delete the mishomed tasks."},{"line_number":160,"context_line":""},{"line_number":161,"context_line":"By default the tool runs on only the \"next days\" worth of task_containers, this"},{"line_number":162,"context_line":"works well to help ops estimate the runtime to process the entire queue. You\u0027ll"},{"line_number":163,"context_line":"need to run the ``swift-expirer-rebalancer`` multiple times with increasing"},{"line_number":164,"context_line":"values for ``--num-days`` in order to process the entire expirer queue. You can"},{"line_number":165,"context_line":"use the ``--start-day-offset`` to avoid re-evaluating sections of the"}],"source_content_type":"text/x-rst","patch_set":16,"id":"4c68ab04_cd41bcd3","line":162,"range":{"start_line":162,"start_character":14,"end_line":162,"end_character":71},"in_reply_to":"88b9ca11_d4458b0e","updated":"2025-02-11 03:32:52.000000000","message":"good point, let\u0027s close the loop by landing that patch upstream","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":169,"context_line":"rebalancing, in order to check how many deletion tasks would be moved."},{"line_number":170,"context_line":""},{"line_number":171,"context_line":"The ``swift-expirer-rebalancer`` tool is designed to be idempotent and can"},{"line_number":172,"context_line":"safely be run as many times as needed."},{"line_number":173,"context_line":""},{"line_number":174,"context_line":"Upgrading impact: General Task Queue vs Legacy Queue"},{"line_number":175,"context_line":"----------------------------------------------------"}],"source_content_type":"text/x-rst","patch_set":16,"id":"2ab86432_0371a47b","line":172,"updated":"2025-02-07 23:05:28.000000000","message":"Surely we could document some sort of completion criteria. How does an operator know whether they\u0027re done or they need to bump the `--num-days`/`--start-day-offset`?","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"c46c694f81c33146a5f4608ecdd4b3575c4dd60c","unresolved":true,"context_lines":[{"line_number":145,"context_line":"native sharding threshold for containers (1M by default, i.e. more than 100M"},{"line_number":146,"context_line":"delete tasks per day) you will want to increase the configured value of"},{"line_number":147,"context_line":"``expiring_objects_task_container_per_day``. Please note that this config needs"},{"line_number":148,"context_line":"to be changed on both object-server, expirer and proxy-server."},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"When changing the value of ``expiring_objects_task_container_per_day`` many of"},{"line_number":151,"context_line":"the pre-existing enqueued expiration tasks will be in the \"wrong"}],"source_content_type":"text/x-rst","patch_set":17,"id":"e029bd8f_6d0d1d44","line":148,"range":{"start_line":148,"start_character":22,"end_line":148,"end_character":62},"updated":"2025-02-11 22:20:59.000000000","message":"That is a lot of places. Random thought, but because there are some many places is this a candidate for a swift contraint that can be overrided in swift.conf. Then it only needs to be in one place... although it is expirer related so might not make sense.\n\nJust spit balling.","commit_id":"343e8bb33cc7d8787d62052f94873e68bb3db5ae"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"e3ef589f6fb09a325d1e12aa321ab27ed1ea80ad","unresolved":true,"context_lines":[{"line_number":145,"context_line":"native sharding threshold for containers (1M by default, i.e. more than 100M"},{"line_number":146,"context_line":"delete tasks per day) you will want to increase the configured value of"},{"line_number":147,"context_line":"``expiring_objects_task_container_per_day``. Please note that this config needs"},{"line_number":148,"context_line":"to be changed on both object-server, expirer and proxy-server."},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"When changing the value of ``expiring_objects_task_container_per_day`` many of"},{"line_number":151,"context_line":"the pre-existing enqueued expiration tasks will be in the \"wrong"}],"source_content_type":"text/x-rst","patch_set":17,"id":"02f4b360_3ac575a7","line":148,"range":{"start_line":148,"start_character":22,"end_line":148,"end_character":62},"in_reply_to":"e029bd8f_6d0d1d44","updated":"2025-02-12 00:59:49.000000000","message":"yeah, it\u0027s only related to expirer, even though it shows up in three config files.\n\nI did bring up the same question and discussed with @clay.gerrard@gmail.com and @alistairncoles@gmail.com, on one hand swift has other configs that are used on multiple server roles; on the other hand, it\u0027s an advantage to be able use different value on different roles as Al pointed out: when one unexpected situation showed up when rolled out this new config into clusters, one of possible fixes was to change the config value only on one server role.","commit_id":"343e8bb33cc7d8787d62052f94873e68bb3db5ae"}],"etc/proxy-server.conf-sample":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":42,"context_line":"# scalability; otherwise the default is quite good"},{"line_number":43,"context_line":"# N.B. it MUST be kept consistent with object-[server|expirer].conf and MUST"},{"line_number":44,"context_line":"# be less than 86400"},{"line_number":45,"context_line":"# expiring_objects_task_container_per_day \u003d 100"},{"line_number":46,"context_line":"#"},{"line_number":47,"context_line":"# You can specify default log routing here if you want:"},{"line_number":48,"context_line":"# log_name \u003d swift"}],"source_content_type":"application/octet-stream","patch_set":16,"id":"db21242e_226ab952","line":45,"range":{"start_line":45,"start_character":24,"end_line":45,"end_character":33},"updated":"2025-02-07 23:05:28.000000000","message":"It feels a little odd to me that this is singular instead of plural...","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":true,"context_lines":[{"line_number":42,"context_line":"# scalability; otherwise the default is quite good"},{"line_number":43,"context_line":"# N.B. it MUST be kept consistent with object-[server|expirer].conf and MUST"},{"line_number":44,"context_line":"# be less than 86400"},{"line_number":45,"context_line":"# expiring_objects_task_container_per_day \u003d 100"},{"line_number":46,"context_line":"#"},{"line_number":47,"context_line":"# You can specify default log routing here if you want:"},{"line_number":48,"context_line":"# log_name \u003d swift"}],"source_content_type":"application/octet-stream","patch_set":16,"id":"d5755ea0_d71338b6","line":45,"range":{"start_line":45,"start_character":24,"end_line":45,"end_character":33},"in_reply_to":"db21242e_226ab952","updated":"2025-02-11 03:32:52.000000000","message":"ACK. but we are already carrying this patch in the prod and the new config ``expiring_objects_task_container_per_day`` goes with this too :-(","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"}],"swift/cli/expirer_rebalance.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1c4c6823d33c2e6f78d03395f7545f43d12e80b6","unresolved":true,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2024 NVIDIA"},{"line_number":2,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not"},{"line_number":3,"context_line":"# use this file except in compliance with the License. You may obtain a copy"},{"line_number":4,"context_line":"# of the License at"}],"source_content_type":"text/x-python","patch_set":1,"id":"1fed2a96_89ac7110","line":1,"updated":"2024-10-28 13:32:16.000000000","message":"Most cli scripts are named ending ``-er`` so I expected this file to be named ``expirer-rebalancer.py`` (and the commit message suggests that is the intent)","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b85c9d374e62915a3b8d023ef0e463df5fb923b","unresolved":false,"context_lines":[{"line_number":1,"context_line":"# Copyright (c) 2024 NVIDIA"},{"line_number":2,"context_line":"# Licensed under the Apache License, Version 2.0 (the \"License\"); you may not"},{"line_number":3,"context_line":"# use this file except in compliance with the License. You may obtain a copy"},{"line_number":4,"context_line":"# of the License at"}],"source_content_type":"text/x-python","patch_set":1,"id":"efd90fc8_21567c59","line":1,"in_reply_to":"1fed2a96_89ac7110","updated":"2024-10-28 23:05:15.000000000","message":"well that was fun.  good call.","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1c4c6823d33c2e6f78d03395f7545f43d12e80b6","unresolved":true,"context_lines":[{"line_number":282,"context_line":"    args.result_q.put(dict(args.stats))"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"def parse_args(args\u003dNone, conf\u003dNone, logger\u003dNone, container_ring\u003dNone):"},{"line_number":286,"context_line":"    args \u003d parser.parse_args(args)"},{"line_number":287,"context_line":"    conf \u003d conf if conf is not None else readconf("},{"line_number":288,"context_line":"        args.expirer_config, \u0027object-expirer\u0027, log_name\u003d\u0027expirer-rebalancer\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"798d24e3_9734f5e7","line":285,"updated":"2024-10-28 13:32:16.000000000","message":"when does this get called with args?","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":282,"context_line":"    args.result_q.put(dict(args.stats))"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"def parse_args(args\u003dNone, conf\u003dNone, logger\u003dNone, container_ring\u003dNone):"},{"line_number":286,"context_line":"    args \u003d parser.parse_args(args)"},{"line_number":287,"context_line":"    conf \u003d conf if conf is not None else readconf("},{"line_number":288,"context_line":"        args.expirer_config, \u0027object-expirer\u0027, log_name\u003d\u0027expirer-rebalancer\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"5cec8616_273c929e","line":285,"in_reply_to":"4603eed9_d44c15be","updated":"2024-11-05 00:23:25.000000000","message":"Done","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b85c9d374e62915a3b8d023ef0e463df5fb923b","unresolved":true,"context_lines":[{"line_number":282,"context_line":"    args.result_q.put(dict(args.stats))"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"def parse_args(args\u003dNone, conf\u003dNone, logger\u003dNone, container_ring\u003dNone):"},{"line_number":286,"context_line":"    args \u003d parser.parse_args(args)"},{"line_number":287,"context_line":"    conf \u003d conf if conf is not None else readconf("},{"line_number":288,"context_line":"        args.expirer_config, \u0027object-expirer\u0027, log_name\u003d\u0027expirer-rebalancer\u0027)"}],"source_content_type":"text/x-python","patch_set":1,"id":"4603eed9_d44c15be","line":285,"in_reply_to":"798d24e3_9734f5e7","updated":"2024-10-28 23:05:15.000000000","message":"I probably had intended to pull more of the meat out of main and patching the args creation was just a (failed) stop-gap.","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1c4c6823d33c2e6f78d03395f7545f43d12e80b6","unresolved":true,"context_lines":[{"line_number":287,"context_line":"    conf \u003d conf if conf is not None else readconf("},{"line_number":288,"context_line":"        args.expirer_config, \u0027object-expirer\u0027, log_name\u003d\u0027expirer-rebalancer\u0027)"},{"line_number":289,"context_line":"    args.logger \u003d logger or get_logger(conf)"},{"line_number":290,"context_line":"    set_verbosity_level(args.verbose, logger)"},{"line_number":291,"context_line":"    # gross that expirer_config is a path and expirer_conf is an object?"},{"line_number":292,"context_line":"    args.expirer_conf \u003d ExpirerConfig(conf)"},{"line_number":293,"context_line":"    args.internal_client_conf_path \u003d conf.get("}],"source_content_type":"text/x-python","patch_set":1,"id":"9d81039b_913e25fb","line":290,"range":{"start_line":290,"start_character":38,"end_line":290,"end_character":44},"updated":"2024-10-28 13:32:16.000000000","message":"args.logger","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":287,"context_line":"    conf \u003d conf if conf is not None else readconf("},{"line_number":288,"context_line":"        args.expirer_config, \u0027object-expirer\u0027, log_name\u003d\u0027expirer-rebalancer\u0027)"},{"line_number":289,"context_line":"    args.logger \u003d logger or get_logger(conf)"},{"line_number":290,"context_line":"    set_verbosity_level(args.verbose, logger)"},{"line_number":291,"context_line":"    # gross that expirer_config is a path and expirer_conf is an object?"},{"line_number":292,"context_line":"    args.expirer_conf \u003d ExpirerConfig(conf)"},{"line_number":293,"context_line":"    args.internal_client_conf_path \u003d conf.get("}],"source_content_type":"text/x-python","patch_set":1,"id":"f96e61d0_5d3e5f41","line":290,"range":{"start_line":290,"start_character":38,"end_line":290,"end_character":44},"in_reply_to":"5e66e705_b96522d5","updated":"2024-11-05 00:23:25.000000000","message":"Done","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b85c9d374e62915a3b8d023ef0e463df5fb923b","unresolved":true,"context_lines":[{"line_number":287,"context_line":"    conf \u003d conf if conf is not None else readconf("},{"line_number":288,"context_line":"        args.expirer_config, \u0027object-expirer\u0027, log_name\u003d\u0027expirer-rebalancer\u0027)"},{"line_number":289,"context_line":"    args.logger \u003d logger or get_logger(conf)"},{"line_number":290,"context_line":"    set_verbosity_level(args.verbose, logger)"},{"line_number":291,"context_line":"    # gross that expirer_config is a path and expirer_conf is an object?"},{"line_number":292,"context_line":"    args.expirer_conf \u003d ExpirerConfig(conf)"},{"line_number":293,"context_line":"    args.internal_client_conf_path \u003d conf.get("}],"source_content_type":"text/x-python","patch_set":1,"id":"5e66e705_b96522d5","line":290,"range":{"start_line":290,"start_character":38,"end_line":290,"end_character":44},"in_reply_to":"9d81039b_913e25fb","updated":"2024-10-28 23:05:15.000000000","message":"I think I got disgusted with all this attribute setting just enough to recognize all these \"fuctions\" that take an \"args\" param \u0027ought just be methods on a class and use self like I\u0027ve written software before - but apparently not quite frustrated enough to actually attempt the refactor.","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"1c4c6823d33c2e6f78d03395f7545f43d12e80b6","unresolved":true,"context_lines":[{"line_number":293,"context_line":"    args.internal_client_conf_path \u003d conf.get("},{"line_number":294,"context_line":"        \u0027internal_client_conf_path\u0027, \u0027/etc/swift/internal-client.conf\u0027)"},{"line_number":295,"context_line":"    args.now \u003d datetime.datetime.now()"},{"line_number":296,"context_line":"    args.logger \u003d logger"},{"line_number":297,"context_line":"    # somewhat gross, this will get overridden in internal_client_ctx"},{"line_number":298,"context_line":"    args.container_ring \u003d container_ring"},{"line_number":299,"context_line":"    args.stats \u003d defaultdict(int)"}],"source_content_type":"text/x-python","patch_set":1,"id":"cf22131c_7fe29aa7","line":296,"updated":"2024-10-28 13:32:16.000000000","message":"remove this line","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b85c9d374e62915a3b8d023ef0e463df5fb923b","unresolved":false,"context_lines":[{"line_number":293,"context_line":"    args.internal_client_conf_path \u003d conf.get("},{"line_number":294,"context_line":"        \u0027internal_client_conf_path\u0027, \u0027/etc/swift/internal-client.conf\u0027)"},{"line_number":295,"context_line":"    args.now \u003d datetime.datetime.now()"},{"line_number":296,"context_line":"    args.logger \u003d logger"},{"line_number":297,"context_line":"    # somewhat gross, this will get overridden in internal_client_ctx"},{"line_number":298,"context_line":"    args.container_ring \u003d container_ring"},{"line_number":299,"context_line":"    args.stats \u003d defaultdict(int)"}],"source_content_type":"text/x-python","patch_set":1,"id":"d73d0efb_e52dc156","line":296,"in_reply_to":"cf22131c_7fe29aa7","updated":"2024-10-28 23:05:15.000000000","message":"oic, it\u0027s duplicated with L289","commit_id":"2bcd3a9800abe10b53c4021afce0ed031e3e9d2c"}],"swift/cli/expirer_rebalancer.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5f3cef50aec56551b2d628014246612b77d1eaa1","unresolved":true,"context_lines":[{"line_number":44,"context_line":"                    help\u003d\u0027increase verbosity\u0027)"},{"line_number":45,"context_line":"# main options"},{"line_number":46,"context_line":"parser.add_argument(\u0027--workers\u0027, type\u003dint, default\u003d3,"},{"line_number":47,"context_line":"                    help\u003d\u0027listing worker processes\u0027)"},{"line_number":48,"context_line":"parser.add_argument(\u0027--start-day-offset\u0027, type\u003dint, default\u003d0,"},{"line_number":49,"context_line":"                    help\u003d\"how many days from today (positive or negative) \""},{"line_number":50,"context_line":"                    \"to start the task_container search for movable tasks\")"}],"source_content_type":"text/x-python","patch_set":3,"id":"b99455d6_cef9fdb5","line":47,"range":{"start_line":47,"start_character":26,"end_line":47,"end_character":33},"updated":"2024-10-31 19:19:33.000000000","message":"This makes it sound like that\u0027s all the worker\u0027s doing -- but it\u0027s doing the queue migration, too, right?","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":44,"context_line":"                    help\u003d\u0027increase verbosity\u0027)"},{"line_number":45,"context_line":"# main options"},{"line_number":46,"context_line":"parser.add_argument(\u0027--workers\u0027, type\u003dint, default\u003d3,"},{"line_number":47,"context_line":"                    help\u003d\u0027listing worker processes\u0027)"},{"line_number":48,"context_line":"parser.add_argument(\u0027--start-day-offset\u0027, type\u003dint, default\u003d0,"},{"line_number":49,"context_line":"                    help\u003d\"how many days from today (positive or negative) \""},{"line_number":50,"context_line":"                    \"to start the task_container search for movable tasks\")"}],"source_content_type":"text/x-python","patch_set":3,"id":"a8b753fb_e97856ea","line":47,"range":{"start_line":47,"start_character":26,"end_line":47,"end_character":33},"in_reply_to":"b99455d6_cef9fdb5","updated":"2024-11-05 00:23:25.000000000","message":"yes, they list and move - removed the word \"listing\" from this arguments help text.","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5f3cef50aec56551b2d628014246612b77d1eaa1","unresolved":true,"context_lines":[{"line_number":49,"context_line":"                    help\u003d\"how many days from today (positive or negative) \""},{"line_number":50,"context_line":"                    \"to start the task_container search for movable tasks\")"},{"line_number":51,"context_line":"parser.add_argument(\u0027--num-days\u0027, type\u003dint, default\u003d1,"},{"line_number":52,"context_line":"                    help\u003d\"How many task_container days to move\")"},{"line_number":53,"context_line":"# worker options"},{"line_number":54,"context_line":"parser.add_argument(\u0027--concurrency\u0027, type\u003dint, default\u003d10,"},{"line_number":55,"context_line":"                    help\u003d\u0027number of concurrent tasks per worker\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"449c9aac_7c38b3ea","line":52,"updated":"2024-10-31 19:19:33.000000000","message":"Is there any way to tell it \"process all queue entries\"? I guess, `--num-days\u003d99999999999999999999999999999999999999999` or something?\n\nHow will operators know when they\u0027re \"done\"?","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":49,"context_line":"                    help\u003d\"how many days from today (positive or negative) \""},{"line_number":50,"context_line":"                    \"to start the task_container search for movable tasks\")"},{"line_number":51,"context_line":"parser.add_argument(\u0027--num-days\u0027, type\u003dint, default\u003d1,"},{"line_number":52,"context_line":"                    help\u003d\"How many task_container days to move\")"},{"line_number":53,"context_line":"# worker options"},{"line_number":54,"context_line":"parser.add_argument(\u0027--concurrency\u0027, type\u003dint, default\u003d10,"},{"line_number":55,"context_line":"                    help\u003d\u0027number of concurrent tasks per worker\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"79641e32_8e6954f3","line":52,"in_reply_to":"0806f9c5_5d40d8e9","updated":"2025-02-07 23:05:28.000000000","message":"I appreciate the addition of https://review.opendev.org/c/openstack/swift/+/933373/3..16/doc/source/overview_expiring_objects.rst -- but I\u0027m still struggling a little just to figure out what\u0027s getting processed by default. I would\u0027ve thought that uploading an object with an expiry in the near future would work out ok:\n```\nvagrant@saio:~/swift$ \u003c/dev/null swift upload -H x-delete-after:3600 c - --object-name ß\nß\n```\nNope; even after running my updaters, I just see it skip the one and only piece of work:\n```\nvagrant@saio:~/swift$ swift-expirer-rebalancer /etc/swift/object-expirer.conf.d/ -v --workers 1\nexpirer-rebalancer-ic: - - 07/Feb/2025/22/22/13 GET /v1/.expiring_objects%3Fformat%3Djson%26marker%3D%26end_marker%3D%26prefix%3D HTTP/1.0 200 - expirer-rebalancer - - 95 - tx33e1bcfa7a1c4490aca0c-0067a68795 - 0.0219 - - 1738966933.264591932 1738966933.286502123 -\nexpirer-rebalancer: skipping task_container 1738886399 due in -1 days with 1 tasks\nexpirer-rebalancer-ic: - - 07/Feb/2025/22/22/13 GET /v1/.expiring_objects%3Fformat%3Djson%26marker%3D1738886399%26end_marker%3D%26prefix%3D HTTP/1.0 200 - expirer-rebalancer - - 2 - tx29716db5d7754fc7b4da3-0067a68795 - 0.0030 - - 1738966933.287897348 1738966933.290898323 -\nexpirer-rebalancer: found 0 task_containers w/ 0 tasks to evaluate\nexpirer-rebalancer: waiting on listing workers\n14 RLock(s) were not greened, to fix this error make sure you run eventlet.monkey_patch() before importing any other modules.\nexpirer-rebalancer: [worker 0/1 pid\u003d54307] listed 0 task_containers and queued 0/0 tasks\nexpirer-rebalancer: [worker 0/1 pid\u003d54307] waiting on greenthreads\ndone\n```\nApparently I needed a ` --start-day-offset -1`?\n\n---\n\n\u003e work their way out to processing the long tail.\n\nStill, the question remains: How will operators know when they\u0027re \"done\"?","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":true,"context_lines":[{"line_number":49,"context_line":"                    help\u003d\"how many days from today (positive or negative) \""},{"line_number":50,"context_line":"                    \"to start the task_container search for movable tasks\")"},{"line_number":51,"context_line":"parser.add_argument(\u0027--num-days\u0027, type\u003dint, default\u003d1,"},{"line_number":52,"context_line":"                    help\u003d\"How many task_container days to move\")"},{"line_number":53,"context_line":"# worker options"},{"line_number":54,"context_line":"parser.add_argument(\u0027--concurrency\u0027, type\u003dint, default\u003d10,"},{"line_number":55,"context_line":"                    help\u003d\u0027number of concurrent tasks per worker\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"0806f9c5_5d40d8e9","line":52,"in_reply_to":"449c9aac_7c38b3ea","updated":"2024-11-05 00:23:25.000000000","message":"maybe reasonable to have an option to just keep listing until you run out of containers (or memory)\n\nPart of the problem with that as a default behavior is going to be the unknown density of the expirer queue in peoples production containers.  We have 3M task containers:\n\n```\nContainers: 3059261\n```\n\nThat might be more than we want to build in a list and farm out to workers all at once.  We could re-word the loop to pull some number of days worth of containers to distribute out to launched workers, wait for the workers to finish, then spawn some more workers with the next batch.  But the parent process is going to have to keep going into and out of eventlet-land/internal_client_ctx to keep the forking safe.\n\nMy assumption would be someone that needs to reconfigure task_container_per_day is probably going to take the same approach we did: start with a few days and then work their way out to processing the long tail.\n\nWe could add some notes on our methodology to expirer docs and let further patches to enhance the ergonomics come later if anyone else needed them.","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"109c9aa3d733c5a6669f41751d5a042beb025319","unresolved":true,"context_lines":[{"line_number":58,"context_line":"parser.add_argument(\u0027--limit-per-task-container\u0027, type\u003dint, default\u003dNone,"},{"line_number":59,"context_line":"                    help\u003d\u0027Only process a few task entries per task_container\u0027)"},{"line_number":60,"context_line":"parser.add_argument(\u0027--dry-run\u0027, action\u003d\u0027store_true\u0027,"},{"line_number":61,"context_line":"                    help\u003d\u0027do not move anything\u0027)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"def direct_put_container_entry(container_ring, account_name, container_name,"}],"source_content_type":"text/x-python","patch_set":3,"id":"cecbae37_90843f8f","line":61,"updated":"2025-02-07 21:39:13.000000000","message":"Anything to override the source/destination account? I think this could *almost* be used to migrate off a non-standard `expiring_objects_account_name` but not quite yet...","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":true,"context_lines":[{"line_number":58,"context_line":"parser.add_argument(\u0027--limit-per-task-container\u0027, type\u003dint, default\u003dNone,"},{"line_number":59,"context_line":"                    help\u003d\u0027Only process a few task entries per task_container\u0027)"},{"line_number":60,"context_line":"parser.add_argument(\u0027--dry-run\u0027, action\u003d\u0027store_true\u0027,"},{"line_number":61,"context_line":"                    help\u003d\u0027do not move anything\u0027)"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":""},{"line_number":64,"context_line":"def direct_put_container_entry(container_ring, account_name, container_name,"}],"source_content_type":"text/x-python","patch_set":3,"id":"f6618bf0_51cfe892","line":61,"in_reply_to":"cecbae37_90843f8f","updated":"2025-02-11 03:32:52.000000000","message":"it\u0027s doable, but maybe it\u0027s easier to clean the existing deletion tasks in the legacy expiring account with standalone expirers and legacy config.","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5f3cef50aec56551b2d628014246612b77d1eaa1","unresolved":true,"context_lines":[{"line_number":108,"context_line":"            logger \u003d args.logger"},{"line_number":109,"context_line":"        else:"},{"line_number":110,"context_line":"            logger \u003d get_logger("},{"line_number":111,"context_line":"                self.conf, log_to_console\u003dargs.verbose \u003e 0)"},{"line_number":112,"context_line":"        verbose_map \u003d {"},{"line_number":113,"context_line":"            0: logging.ERROR,"},{"line_number":114,"context_line":"            1: logging.INFO,"}],"source_content_type":"text/x-python","patch_set":3,"id":"c3a7326f_08f752b5","line":111,"range":{"start_line":111,"start_character":42,"end_line":111,"end_character":58},"updated":"2024-10-31 19:19:33.000000000","message":"So nothing (not even errors) goes to the console by default, just to syslog?","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":true,"context_lines":[{"line_number":108,"context_line":"            logger \u003d args.logger"},{"line_number":109,"context_line":"        else:"},{"line_number":110,"context_line":"            logger \u003d get_logger("},{"line_number":111,"context_line":"                self.conf, log_to_console\u003dargs.verbose \u003e 0)"},{"line_number":112,"context_line":"        verbose_map \u003d {"},{"line_number":113,"context_line":"            0: logging.ERROR,"},{"line_number":114,"context_line":"            1: logging.INFO,"}],"source_content_type":"text/x-python","patch_set":3,"id":"a95f7529_1fe68b90","line":111,"range":{"start_line":111,"start_character":42,"end_line":111,"end_character":58},"in_reply_to":"c0192a22_674dc319","updated":"2024-11-05 00:23:25.000000000","message":"i might should require `args.verbose \u0026\u0026 args.workers \u003d 1` before even attempting to use `log_to_console`...","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"281381d987650152c84d7e3720d36bd6a7149795","unresolved":true,"context_lines":[{"line_number":108,"context_line":"            logger \u003d args.logger"},{"line_number":109,"context_line":"        else:"},{"line_number":110,"context_line":"            logger \u003d get_logger("},{"line_number":111,"context_line":"                self.conf, log_to_console\u003dargs.verbose \u003e 0)"},{"line_number":112,"context_line":"        verbose_map \u003d {"},{"line_number":113,"context_line":"            0: logging.ERROR,"},{"line_number":114,"context_line":"            1: logging.INFO,"}],"source_content_type":"text/x-python","patch_set":3,"id":"c0192a22_674dc319","line":111,"range":{"start_line":111,"start_character":42,"end_line":111,"end_character":58},"in_reply_to":"c3a7326f_08f752b5","updated":"2024-11-01 21:50:06.000000000","message":"logging to the console from multiple workers is actually a huge mess - you can\u0027t really do IPC using mp module when you have eventlet green threads running.","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"109c9aa3d733c5a6669f41751d5a042beb025319","unresolved":true,"context_lines":[{"line_number":273,"context_line":"        \"\"\""},{"line_number":274,"context_line":"        with super(RebalancerWorker, self).internal_client_ctx() as ic:"},{"line_number":275,"context_line":"            self.container_ring \u003d ic.container_ring"},{"line_number":276,"context_line":"            yield ic"},{"line_number":277,"context_line":""},{"line_number":278,"context_line":"    def process(self, task_containers):"},{"line_number":279,"context_line":"        with self.internal_client_ctx() as swift:"}],"source_content_type":"text/x-python","patch_set":3,"id":"a0727fbc_d19c7451","line":276,"updated":"2025-02-07 21:39:13.000000000","message":"nit: Should we set\n```\nself.container_ring \u003d None\n```\nafter the yield? And maybe up in `__init__`?","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":273,"context_line":"        \"\"\""},{"line_number":274,"context_line":"        with super(RebalancerWorker, self).internal_client_ctx() as ic:"},{"line_number":275,"context_line":"            self.container_ring \u003d ic.container_ring"},{"line_number":276,"context_line":"            yield ic"},{"line_number":277,"context_line":""},{"line_number":278,"context_line":"    def process(self, task_containers):"},{"line_number":279,"context_line":"        with self.internal_client_ctx() as swift:"}],"source_content_type":"text/x-python","patch_set":3,"id":"45c5cb3f_8630560d","line":276,"in_reply_to":"a0727fbc_d19c7451","updated":"2025-02-11 03:32:52.000000000","message":"Done","commit_id":"5fb992f28f828dc84e80527d9962b922c6067e5e"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"281381d987650152c84d7e3720d36bd6a7149795","unresolved":true,"context_lines":[{"line_number":365,"context_line":"    def run_workers(self, args, task_containers):"},{"line_number":366,"context_line":"        result_q \u003d self._get_queue()"},{"line_number":367,"context_line":"        workers \u003d self._spawn_workers(args, task_containers, result_q)"},{"line_number":368,"context_line":"        # XXX this can deadlock if there\u0027s a lot of workers that finish early"},{"line_number":369,"context_line":"        # and the result_q gets full"},{"line_number":370,"context_line":"        self.logger.info(\u0027waiting on listing workers\u0027)"},{"line_number":371,"context_line":"        for worker in workers:"}],"source_content_type":"text/x-python","patch_set":4,"id":"75548ad2_6c721aa3","line":368,"updated":"2024-11-01 21:50:06.000000000","message":"oh yeah, this is real - we can just join workers as we drain the queue.  it\u0027s hard to write tests for multiprocessing because unittests spawn greenthreads and leave them running all over the place.  But the same principle would apply to greenthread workers and eventlet queue so maybe I can demonstrate this code needs that kind of fix using a fakey green kind of test.","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0af0690936ef16c69504b67ee1f4e7b13531c4e5","unresolved":true,"context_lines":[{"line_number":263,"context_line":"                        moved_tasks \u003e\u003d self.limit_per_task_container):"},{"line_number":264,"context_line":"                    break"},{"line_number":265,"context_line":"        self.logger.info(\u0027found %s mis-queued tasks in %s\u0027,"},{"line_number":266,"context_line":"                         moved_tasks, task_container[\u0027name\u0027])"},{"line_number":267,"context_line":"        return moved_tasks"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    @contextlib.contextmanager"}],"source_content_type":"text/x-python","patch_set":5,"id":"06559eba_048b8233","line":266,"updated":"2024-11-04 10:55:22.000000000","message":"it\u0027s unfortunate that this log message is lost when an Unexpected Response is raised, rather than getting a log like \u0027found %s mis-queued tasks in %s (terminated early)\u0027 or similar:\n\ne.g. from tests, only 2 of the 3 containers get progress logged:\n\n```\ntest_expirer_rebalancer.py::TestExpirerRebalance::test_process_task_containers_errors FAILED [100%]num objects 10\nnum objects 10\nnum objects 12\ntest INFO: [MainProcess pid\u003d47597] found 10 mis-queued tasks in 1730678302\ntest ERROR: [MainProcess pid\u003d47597] error listing tasks in {\u0027name\u0027: \u00271730678351\u0027, \u0027count\u0027: 10, \u0027bytes\u0027: 0, \u0027last_modified\u0027: \u00272024-10-17T18:10:07.076510\u0027, \u0027rebalance_day_delta\u0027: 0}: \nTraceback (most recent call last):\n  File \"/Users/acoles/0dev/openstack/swift/swift/cli/expirer_rebalancer.py\", line 286, in process\n    worker_tasks +\u003d self.process_task_container(\n                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/Users/acoles/0dev/openstack/swift/swift/cli/expirer_rebalancer.py\", line 240, in process_task_container\n    for task_obj in swift.iter_objects(\n  File \"/Users/acoles/0dev/openstack/swift/swift/common/internal_client.py\", line 331, in _iter_items\n    resp \u003d self.make_request(\n           ^^^^^^^^^^^^^^^^^^\n  File \"/Users/acoles/0dev/openstack/swift/swift/common/internal_client.py\", line 258, in make_request\n    raise UnexpectedResponse(msg, resp)\nswift.common.internal_client.UnexpectedResponse: Unexpected response: 500 Internal Error (b\u0027Try Again\u0027)\ncorrect\ntest INFO: [MainProcess pid\u003d47597] found 11 mis-queued tasks in 1730678376\ntest INFO: [MainProcess pid\u003d47597] listed 3 task_containers and queued 21/32 tasks\ntest INFO: [MainProcess pid\u003d47597] waiting on greenthreads\n```","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":263,"context_line":"                        moved_tasks \u003e\u003d self.limit_per_task_container):"},{"line_number":264,"context_line":"                    break"},{"line_number":265,"context_line":"        self.logger.info(\u0027found %s mis-queued tasks in %s\u0027,"},{"line_number":266,"context_line":"                         moved_tasks, task_container[\u0027name\u0027])"},{"line_number":267,"context_line":"        return moved_tasks"},{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    @contextlib.contextmanager"}],"source_content_type":"text/x-python","patch_set":5,"id":"2fc560ff_9f1c3251","line":266,"in_reply_to":"06559eba_048b8233","updated":"2024-11-05 00:23:25.000000000","message":"I feel like any value for `moved_tasks` when there\u0027s an error would be un-reliable at best - I think the traceback is sufficient for someone trying to track what happened if the value reported moved at the end of process is less than they expected.","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":true,"context_lines":[{"line_number":285,"context_line":"                        swift, task_container, pool)"},{"line_number":286,"context_line":"                except UnexpectedResponse:"},{"line_number":287,"context_line":"                    self.logger.exception("},{"line_number":288,"context_line":"                        \u0027error listing tasks in %s\u0027 % task_container)"},{"line_number":289,"context_line":""},{"line_number":290,"context_line":"            self.logger.info(\u0027listed %s task_containers \u0027"},{"line_number":291,"context_line":"                             \u0027and queued %s/%s tasks\u0027,"}],"source_content_type":"text/x-python","patch_set":5,"id":"9d248c1e_eb6114f1","line":288,"updated":"2024-11-05 00:23:25.000000000","message":"it\u0027s interesting to consider than in theory some of tasks in this container may have been spawned into the move pool but we\u0027re not incrementing worker_tasks to consider them... perhaps moving the error handling of UnexpectedResponse into `process_task_container` and returning the value of spawned tasks un-conditionally might be better?\n\n```\nall_success \u003d True\nfor c in task_containers:\n    success, spawned_tasks \u003d self.process_task_container()\n    all_success \u003d all_success and success\n...\nif not all_success:\n    log.error(\u0027something went wrong\u0027)\n```","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"70bd0206f0a1e6bdc74ef1420de2cd3d03514d36","unresolved":false,"context_lines":[{"line_number":386,"context_line":"    args \u003d parser.parse_args(args)"},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"    # Ensure workers argument is valid"},{"line_number":389,"context_line":"    if args.workers \u003c\u003d 0:"},{"line_number":390,"context_line":"        raise ValueError(\"The number of workers must be greater than 0.\")"},{"line_number":391,"context_line":""},{"line_number":392,"context_line":"    expirer_rebalancer \u003d ExpirerRebalancer(args)"}],"source_content_type":"text/x-python","patch_set":5,"id":"a9bd50cd_46ee9853","line":389,"updated":"2024-11-04 05:20:47.000000000","message":"we shouldn\u0027t allow ``args.workers \u003d 0``","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"38bc0e8c4439c35c154027fecd03535482528bdd","unresolved":true,"context_lines":[{"line_number":117,"context_line":"        }"},{"line_number":118,"context_line":"        log_level \u003d verbose_map.get(args.verbose, logging.DEBUG)"},{"line_number":119,"context_line":"        if six.PY2:"},{"line_number":120,"context_line":"            logger.logger.setLevel(log_level)"},{"line_number":121,"context_line":"        else:"},{"line_number":122,"context_line":"            logger.setLevel(log_level)"},{"line_number":123,"context_line":"        return logger"}],"source_content_type":"text/x-python","patch_set":7,"id":"bf849f0b_f3849f8b","line":120,"updated":"2024-11-05 22:53:43.000000000","message":"this was a surprising attribute error in py2 tests","commit_id":"be09569733934165fa6b42705c2ffc1ba1d87bad"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"914f404eb803d9bb5c5a96f7c353024b2e809f10","unresolved":false,"context_lines":[{"line_number":117,"context_line":"        }"},{"line_number":118,"context_line":"        log_level \u003d verbose_map.get(args.verbose, logging.DEBUG)"},{"line_number":119,"context_line":"        if six.PY2:"},{"line_number":120,"context_line":"            logger.logger.setLevel(log_level)"},{"line_number":121,"context_line":"        else:"},{"line_number":122,"context_line":"            logger.setLevel(log_level)"},{"line_number":123,"context_line":"        return logger"}],"source_content_type":"text/x-python","patch_set":7,"id":"98c8c391_fb37e00c","line":120,"in_reply_to":"bf849f0b_f3849f8b","updated":"2024-11-18 19:08:42.000000000","message":"Acknowledged","commit_id":"be09569733934165fa6b42705c2ffc1ba1d87bad"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":62,"context_line":"                    help\u003d\u0027do not move anything\u0027)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"def direct_put_container_entry(container_ring, account_name, container_name,"},{"line_number":66,"context_line":"                               object_name, headers\u003dNone):"},{"line_number":67,"context_line":"    \"\"\""},{"line_number":68,"context_line":"    Write directly to primary container servers to create a new expirer task."}],"source_content_type":"text/x-python","patch_set":16,"id":"889f9c8b_4fab35a5","line":65,"updated":"2025-02-07 23:05:28.000000000","message":"It\u0027s weird to me that this isn\u0027t closer to `direct_delete_container_entry`","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":62,"context_line":"                    help\u003d\u0027do not move anything\u0027)"},{"line_number":63,"context_line":""},{"line_number":64,"context_line":""},{"line_number":65,"context_line":"def direct_put_container_entry(container_ring, account_name, container_name,"},{"line_number":66,"context_line":"                               object_name, headers\u003dNone):"},{"line_number":67,"context_line":"    \"\"\""},{"line_number":68,"context_line":"    Write directly to primary container servers to create a new expirer task."}],"source_content_type":"text/x-python","patch_set":16,"id":"9505f376_094e1bf0","line":65,"in_reply_to":"889f9c8b_4fab35a5","updated":"2025-02-11 03:32:52.000000000","message":"Acknowledged","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":71,"context_line":"    headers[USE_REPLICATION_NETWORK_HEADER] \u003d \u0027true\u0027"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    part, nodes \u003d container_ring.get_nodes(account_name, container_name)"},{"line_number":74,"context_line":"    pile \u003d eventlet.GreenPile()"},{"line_number":75,"context_line":"    for node in nodes:"},{"line_number":76,"context_line":"        pile.spawn(direct_put_container_object, node, part, account_name,"},{"line_number":77,"context_line":"                   container_name, object_name, headers\u003dheaders)"}],"source_content_type":"text/x-python","patch_set":16,"id":"b864dee0_fee45165","line":74,"range":{"start_line":74,"start_character":20,"end_line":74,"end_character":29},"updated":"2025-02-07 23:05:28.000000000","message":"`direct_delete_container_entry` uses `GreenPool`; why the difference?","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":true,"context_lines":[{"line_number":71,"context_line":"    headers[USE_REPLICATION_NETWORK_HEADER] \u003d \u0027true\u0027"},{"line_number":72,"context_line":""},{"line_number":73,"context_line":"    part, nodes \u003d container_ring.get_nodes(account_name, container_name)"},{"line_number":74,"context_line":"    pile \u003d eventlet.GreenPile()"},{"line_number":75,"context_line":"    for node in nodes:"},{"line_number":76,"context_line":"        pile.spawn(direct_put_container_object, node, part, account_name,"},{"line_number":77,"context_line":"                   container_name, object_name, headers\u003dheaders)"}],"source_content_type":"text/x-python","patch_set":16,"id":"1044a36a_05470991","line":74,"range":{"start_line":74,"start_character":20,"end_line":74,"end_character":29},"in_reply_to":"b864dee0_fee45165","updated":"2025-02-11 03:32:52.000000000","message":"probably ``direct_delete_container_entry`` is just the best effort for the cleanup of old deletion tasks, it doesn\u0027t hurt to leave some of them accidentally not deleted; while ``direct_put_container_entry`` use ``GreenPile`` which will raise an exception and retry if any primary fail, to make sure expirer won\u0027t skip creating the new deletion task. is this why you chose ``GreenPile`` in the first place? @clay.gerrard@gmail.com","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":false,"context_lines":[{"line_number":73,"context_line":"    part, nodes \u003d container_ring.get_nodes(account_name, container_name)"},{"line_number":74,"context_line":"    pile \u003d eventlet.GreenPile()"},{"line_number":75,"context_line":"    for node in nodes:"},{"line_number":76,"context_line":"        pile.spawn(direct_put_container_object, node, part, account_name,"},{"line_number":77,"context_line":"                   container_name, object_name, headers\u003dheaders)"},{"line_number":78,"context_line":"    # if any primaries fail this will raise an exception"},{"line_number":79,"context_line":"    for v in pile:"}],"source_content_type":"text/x-python","patch_set":16,"id":"526b6c06_7ce22f10","line":76,"range":{"start_line":76,"start_character":19,"end_line":76,"end_character":46},"updated":"2025-02-07 23:05:28.000000000","message":"Right; no `x-backend-accept-redirect`, so we should never need worry about 301s.","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":75,"context_line":"    for node in nodes:"},{"line_number":76,"context_line":"        pile.spawn(direct_put_container_object, node, part, account_name,"},{"line_number":77,"context_line":"                   container_name, object_name, headers\u003dheaders)"},{"line_number":78,"context_line":"    # if any primaries fail this will raise an exception"},{"line_number":79,"context_line":"    for v in pile:"},{"line_number":80,"context_line":"        pass"},{"line_number":81,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"ec73484b_5a8755c7","line":78,"updated":"2025-02-07 23:05:28.000000000","message":"It\u0027s unfortunate that we *rely* upon this throwing up a sizable, basically useless traceback:\n```\nTraceback (most recent call last):\n  File \"/usr/local/lib/python3.12/dist-packages/eventlet/hubs/poll.py\", line 111, in wait\n    listener.cb(fileno)\n  File \"/usr/local/lib/python3.12/dist-packages/eventlet/greenthread.py\", line 265, in main\n    result \u003d function(*args, **kwargs)\n             ^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/vagrant/swift/swift/common/direct_client.py\", line 438, in direct_put_container_object\n    _make_req(node, part, \u0027PUT\u0027, path,\n  File \"/vagrant/swift/swift/common/direct_client.py\", line 121, in _make_req\n    conn \u003d http_connect(ip, port, node[\u0027device\u0027], part,\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/vagrant/swift/swift/common/bufferedhttp.py\", line 235, in http_connect\n    return http_connect_raw(\n           ^^^^^^^^^^^^^^^^^\n  File \"/vagrant/swift/swift/common/bufferedhttp.py\", line 273, in http_connect_raw\n    conn.endheaders()\n  File \"/usr/local/lib/python3.12/dist-packages/eventlet/green/http/client.py\", line 1301, in endheaders\n    self._send_output(message_body, encode_chunked\u003dencode_chunked)\n  File \"/usr/local/lib/python3.12/dist-packages/eventlet/green/http/client.py\", line 1089, in _send_output\n    self.send(msg)\n  File \"/usr/local/lib/python3.12/dist-packages/eventlet/green/http/client.py\", line 1018, in send\n    self.connect()\n  File \"/vagrant/swift/swift/common/bufferedhttp.py\", line 167, in connect\n    ret \u003d HTTPConnection.connect(self)\n          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/usr/local/lib/python3.12/dist-packages/eventlet/green/http/client.py\", line 989, in connect\n    self.sock \u003d self._create_connection(\n                ^^^^^^^^^^^^^^^^^^^^^^^^\n  File \"/usr/local/lib/python3.12/dist-packages/eventlet/green/socket.py\", line 63, in create_connection\n    raise err\n  File \"/usr/local/lib/python3.12/dist-packages/eventlet/green/socket.py\", line 53, in create_connection\n    sock.connect(sa)\n  File \"/usr/local/lib/python3.12/dist-packages/eventlet/greenio/base.py\", line 251, in connect\n    socket_checkerr(fd)\n  File \"/usr/local/lib/python3.12/dist-packages/eventlet/greenio/base.py\", line 50, in socket_checkerr\n    raise OSError(err, errno.errorcode[err])\nConnectionRefusedError: [Errno 111] ECONNREFUSED\n```","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":137,"context_line":"                            global_conf\u003d{\u0027log_name\u0027: log_name})"},{"line_number":138,"context_line":"        yield ic"},{"line_number":139,"context_line":"        # we\u0027re done with the eventlet silliness!"},{"line_number":140,"context_line":"        ic.app._pipeline_final_app.watchdog._run_gth.kill()"},{"line_number":141,"context_line":"        eventlet.hubs.get_hub().abort(wait\u003dTrue)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"fc764d5e_8c0aaf90","line":140,"range":{"start_line":140,"start_character":8,"end_line":140,"end_character":59},"updated":"2025-02-07 23:05:28.000000000","message":"Yowza! Maybe I\u0027d feel better about this if it were at least hidden behind some `InternalClient.close` method?\n\nSurely we could at least use `...watchdog.kill()` instead of grubbing around for `_run_gth` ourselves, yeah?","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":138,"context_line":"        yield ic"},{"line_number":139,"context_line":"        # we\u0027re done with the eventlet silliness!"},{"line_number":140,"context_line":"        ic.app._pipeline_final_app.watchdog._run_gth.kill()"},{"line_number":141,"context_line":"        eventlet.hubs.get_hub().abort(wait\u003dTrue)"},{"line_number":142,"context_line":""},{"line_number":143,"context_line":""},{"line_number":144,"context_line":"def _get_worker_prefix():"}],"source_content_type":"text/x-python","patch_set":16,"id":"1fc75c0f_4dcf34ec","line":141,"updated":"2025-02-07 23:05:28.000000000","message":"I\u0027m kinda amazed that we don\u0027t seem to have any other places where we swing this hammer.","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":203,"context_line":"                        target_task_container,"},{"line_number":204,"context_line":"                        orig_task_info[\u0027orig_task_obj_name\u0027], headers\u003dheaders)"},{"line_number":205,"context_line":"            except eventlet.Timeout:"},{"line_number":206,"context_line":"                self.logger.exception(\u0027timeout writing %r to %r w/ %r\u0027,"},{"line_number":207,"context_line":"                                      orig_task_info,"},{"line_number":208,"context_line":"                                      target_task_container,"},{"line_number":209,"context_line":"                                      headers)"}],"source_content_type":"text/x-python","patch_set":16,"id":"019e6609_372b3188","line":206,"range":{"start_line":206,"start_character":28,"end_line":206,"end_character":37},"updated":"2025-02-07 23:05:28.000000000","message":"We aren\u0027t actually logging any tracebacks, are we? Why not just `error`?","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":203,"context_line":"                        target_task_container,"},{"line_number":204,"context_line":"                        orig_task_info[\u0027orig_task_obj_name\u0027], headers\u003dheaders)"},{"line_number":205,"context_line":"            except eventlet.Timeout:"},{"line_number":206,"context_line":"                self.logger.exception(\u0027timeout writing %r to %r w/ %r\u0027,"},{"line_number":207,"context_line":"                                      orig_task_info,"},{"line_number":208,"context_line":"                                      target_task_container,"},{"line_number":209,"context_line":"                                      headers)"}],"source_content_type":"text/x-python","patch_set":16,"id":"2f8f48ec_b399fd5c","line":206,"range":{"start_line":206,"start_character":28,"end_line":206,"end_character":37},"in_reply_to":"019e6609_372b3188","updated":"2025-02-11 03:32:52.000000000","message":"Done","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":219,"context_line":"                        orig_task_info[\u0027orig_task_container\u0027],"},{"line_number":220,"context_line":"                        orig_task_info[\u0027orig_task_obj_name\u0027])"},{"line_number":221,"context_line":"            except eventlet.Timeout:"},{"line_number":222,"context_line":"                self.logger.exception(\u0027timeout cleaning %r from %r\u0027,"},{"line_number":223,"context_line":"                                      orig_task_info[\u0027orig_task_obj_name\u0027],"},{"line_number":224,"context_line":"                                      orig_task_info[\u0027orig_task_container\u0027])"},{"line_number":225,"context_line":"                raise"}],"source_content_type":"text/x-python","patch_set":16,"id":"c577388e_bbedb492","line":222,"range":{"start_line":222,"start_character":28,"end_line":222,"end_character":37},"updated":"2025-02-07 23:05:28.000000000","message":"ditto","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":219,"context_line":"                        orig_task_info[\u0027orig_task_container\u0027],"},{"line_number":220,"context_line":"                        orig_task_info[\u0027orig_task_obj_name\u0027])"},{"line_number":221,"context_line":"            except eventlet.Timeout:"},{"line_number":222,"context_line":"                self.logger.exception(\u0027timeout cleaning %r from %r\u0027,"},{"line_number":223,"context_line":"                                      orig_task_info[\u0027orig_task_obj_name\u0027],"},{"line_number":224,"context_line":"                                      orig_task_info[\u0027orig_task_container\u0027])"},{"line_number":225,"context_line":"                raise"}],"source_content_type":"text/x-python","patch_set":16,"id":"52e5cca9_8c96e200","line":222,"range":{"start_line":222,"start_character":28,"end_line":222,"end_character":37},"in_reply_to":"c577388e_bbedb492","updated":"2025-02-11 03:32:52.000000000","message":"Done","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3663cc462803e00505c1bcf811c6ed2180fc81a6","unresolved":true,"context_lines":[{"line_number":230,"context_line":"        try:"},{"line_number":231,"context_line":"            self._move_task_object(target_task_container, orig_task_info)"},{"line_number":232,"context_line":"        except Exception:"},{"line_number":233,"context_line":"            self.logger.exception(\u0027unable to move %r to %r\u0027 % ("},{"line_number":234,"context_line":"                orig_task_info, target_task_container))"},{"line_number":235,"context_line":"            self.stats[\u0027failed_tasks\u0027] +\u003d 1"},{"line_number":236,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":16,"id":"715afd48_be9e8a20","line":233,"range":{"start_line":233,"start_character":24,"end_line":233,"end_character":33},"updated":"2025-02-07 23:05:28.000000000","message":"I don\u0027t feel like adding the traceback adds anything of value:\n```\nexpirer-rebalancer: [worker 0/1 pid\u003d54374] unable to move {\u0027orig_task_container\u0027: \u00271738886399\u0027, \u0027x_delete_at\u0027: 1738970477.00000_0000000000000000, \u0027account\u0027: \u0027AUTH_test\u0027, \u0027container\u0027: \u0027c\u0027, \u0027obj\u0027: \u0027ß\u0027, \u0027content_type\u0027: \u0027text/plain;swift_expirer_bytes\u003d0\u0027, \u0027timestamp\u0027: 1738966877.97551_0000000000000000, \u0027orig_task_obj_name\u0027: \u00271738970477-AUTH_test/c/ß\u0027} to \u00271738886396\u0027: \nTraceback (most recent call last):\n  File \"/vagrant/swift/swift/cli/expirer_rebalancer.py\", line 231, in move_task_object\n    self._move_task_object(target_task_container, orig_task_info)\n  File \"/vagrant/swift/swift/cli/expirer_rebalancer.py\", line 211, in _move_task_object\n    self._retry(do_migration)\n  File \"/vagrant/swift/swift/cli/expirer_rebalancer.py\", line 180, in _retry\n    raise Exception(\u0027unable to complete %s after %s errors: %r\u0027 % (\nException: unable to complete do_migration after 4 errors: [ConnectionRefusedError(111, \u0027ECONNREFUSED\u0027), ConnectionRefusedError(111, \u0027ECONNREFUSED\u0027), ConnectionRefusedError(111, \u0027ECONNREFUSED\u0027), ConnectionRefusedError(111, \u0027ECONNREFUSED\u0027)]\n\n```","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":230,"context_line":"        try:"},{"line_number":231,"context_line":"            self._move_task_object(target_task_container, orig_task_info)"},{"line_number":232,"context_line":"        except Exception:"},{"line_number":233,"context_line":"            self.logger.exception(\u0027unable to move %r to %r\u0027 % ("},{"line_number":234,"context_line":"                orig_task_info, target_task_container))"},{"line_number":235,"context_line":"            self.stats[\u0027failed_tasks\u0027] +\u003d 1"},{"line_number":236,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":16,"id":"eff95c93_080fa02a","line":233,"range":{"start_line":233,"start_character":24,"end_line":233,"end_character":33},"in_reply_to":"715afd48_be9e8a20","updated":"2025-02-11 03:32:52.000000000","message":"Acknowledged","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"795d0b42d482336bf48fc8bbb7652973d4e8f51c","unresolved":true,"context_lines":[{"line_number":397,"context_line":"    stats \u003d expirer_rebalancer.run_workers(args, task_containers)"},{"line_number":398,"context_line":"    for k, v in stats.items():"},{"line_number":399,"context_line":"        print(k, v)"},{"line_number":400,"context_line":"    print(\u0027done\u0027)"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":""},{"line_number":403,"context_line":"if __name__ \u003d\u003d \"__main__\":"}],"source_content_type":"text/x-python","patch_set":16,"id":"78820dfd_2bed2c11","line":400,"updated":"2025-02-07 23:09:00.000000000","message":"Surely we could *at least* have this `return 1` or something `if stats.failed_tasks`\n\nThis doesn\u0027t seem great when I know I\u0027ve got half my container servers down:\n```\nvagrant@saio:~/swift$ swift-expirer-rebalancer /etc/swift/object-expirer.conf.d/ \n4 RLock(s) were not greened, to fix this error make sure you run eventlet.monkey_patch() before importing any other modules.\n4 RLock(s) were not greened, to fix this error make sure you run eventlet.monkey_patch() before importing any other modules.\n4 RLock(s) were not greened, to fix this error make sure you run eventlet.monkey_patch() before importing any other modules.\ndone\nvagrant@saio:~/swift$ echo $?\n0\n```\n*Especially* when the upgrade note is just like \"go run this tool\"","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":397,"context_line":"    stats \u003d expirer_rebalancer.run_workers(args, task_containers)"},{"line_number":398,"context_line":"    for k, v in stats.items():"},{"line_number":399,"context_line":"        print(k, v)"},{"line_number":400,"context_line":"    print(\u0027done\u0027)"},{"line_number":401,"context_line":""},{"line_number":402,"context_line":""},{"line_number":403,"context_line":"if __name__ \u003d\u003d \"__main__\":"}],"source_content_type":"text/x-python","patch_set":16,"id":"4fed6f77_65f9f634","line":400,"in_reply_to":"78820dfd_2bed2c11","updated":"2025-02-11 03:32:52.000000000","message":"Done","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2b20e46fb23e6c76910b5ddfc7e2fd25da1569ab","unresolved":true,"context_lines":[{"line_number":398,"context_line":"            args.start_day_offset, args.num_days)"},{"line_number":399,"context_line":"    except Exception as e:"},{"line_number":400,"context_line":"        expirer_rebalancer.logger.exception("},{"line_number":401,"context_line":"            \u0027Failed to get expirering task containers: %s\u0027, e)"},{"line_number":402,"context_line":"        print(err_msg)"},{"line_number":403,"context_line":"        return 1"},{"line_number":404,"context_line":""}],"source_content_type":"text/x-python","patch_set":20,"id":"4cb08e12_3df2d352","line":401,"range":{"start_line":401,"start_character":27,"end_line":401,"end_character":37},"updated":"2025-04-11 09:54:12.000000000","message":"s/expirering/expiring/","commit_id":"3df47bbc917b2464b6ad2c05632945ce4e4a5037"}],"swift/obj/expirer.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2b6600ba12fe57889fdfcc11ca0a784906cab07a","unresolved":false,"context_lines":[{"line_number":458,"context_line":"        if unexpected_task_containers[\u0027count\u0027]:"},{"line_number":459,"context_line":"            self.logger.info("},{"line_number":460,"context_line":"                \u0027processing %s unexpected task containers (e.g. %s) \u0027"},{"line_number":461,"context_line":"                \u0027if you have recently changed your expirer config \u0027"},{"line_number":462,"context_line":"                \u0027you can run swift-expirer-rebalancer.\u0027,"},{"line_number":463,"context_line":"                unexpected_task_containers[\u0027count\u0027],"},{"line_number":464,"context_line":"                \u0027 \u0027.join(unexpected_task_containers[\u0027examples\u0027]))"}],"source_content_type":"text/x-python","patch_set":4,"id":"038cd934_6ef8d0af","line":461,"updated":"2024-11-04 00:44:11.000000000","message":"yep. maybe we can also mention this new containers_per_day setting in the log message, but this is also the only setting which could lead us to here.","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"109c9aa3d733c5a6669f41751d5a042beb025319","unresolved":true,"context_lines":[{"line_number":94,"context_line":"        if self.task_container_per_day \u003e\u003d self.expirer_divisor:"},{"line_number":95,"context_line":"            msg \u003d \u0027expiring_objects_task_container_per_day (%s) MUST be \u0027 \\"},{"line_number":96,"context_line":"                  \u0027less than %d\u0027 \\"},{"line_number":97,"context_line":"                  % (self.task_container_per_day, EXPIRER_CONTAINER_DIVISOR)"},{"line_number":98,"context_line":"            if self.expirer_divisor !\u003d 86400:"},{"line_number":99,"context_line":"                msg +\u003d \u0027; expiring_objects_container_divisor (%s) SHOULD be \u0027 \\"},{"line_number":100,"context_line":"                       \u0027default value of %d\u0027 \\"}],"source_content_type":"text/x-python","patch_set":16,"id":"eba87c11_c3a76dbe","line":97,"range":{"start_line":97,"start_character":50,"end_line":97,"end_character":75},"updated":"2025-02-07 21:39:13.000000000","message":"`self.expirer_divisor` -- otherwise, you can get funky errors like\n```\nValueError: expiring_objects_task_container_per_day (1000) MUST be less than 86400; expiring_objects_container_divisor (100) SHOULD be default value of 86400\n```\n(But 1000 **is** less than 86400! Why\u0027s it a hard error if it\u0027s just telling me I *SHOULD* do something?)","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":94,"context_line":"        if self.task_container_per_day \u003e\u003d self.expirer_divisor:"},{"line_number":95,"context_line":"            msg \u003d \u0027expiring_objects_task_container_per_day (%s) MUST be \u0027 \\"},{"line_number":96,"context_line":"                  \u0027less than %d\u0027 \\"},{"line_number":97,"context_line":"                  % (self.task_container_per_day, EXPIRER_CONTAINER_DIVISOR)"},{"line_number":98,"context_line":"            if self.expirer_divisor !\u003d 86400:"},{"line_number":99,"context_line":"                msg +\u003d \u0027; expiring_objects_container_divisor (%s) SHOULD be \u0027 \\"},{"line_number":100,"context_line":"                       \u0027default value of %d\u0027 \\"}],"source_content_type":"text/x-python","patch_set":16,"id":"06c12fa5_72b4056f","line":97,"range":{"start_line":97,"start_character":50,"end_line":97,"end_character":75},"in_reply_to":"eba87c11_c3a76dbe","updated":"2025-02-11 03:32:52.000000000","message":"Done","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"109c9aa3d733c5a6669f41751d5a042beb025319","unresolved":true,"context_lines":[{"line_number":98,"context_line":"            if self.expirer_divisor !\u003d 86400:"},{"line_number":99,"context_line":"                msg +\u003d \u0027; expiring_objects_container_divisor (%s) SHOULD be \u0027 \\"},{"line_number":100,"context_line":"                       \u0027default value of %d\u0027 \\"},{"line_number":101,"context_line":"                       % (self.expirer_divisor, EXPIRER_CONTAINER_DIVISOR)"},{"line_number":102,"context_line":"            raise ValueError(msg)"},{"line_number":103,"context_line":"        self.container_ring \u003d container_ring"},{"line_number":104,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"471a196e_ea709d51","line":101,"updated":"2025-02-07 21:39:13.000000000","message":"I feel like this should just be a separate warning up around L75 (or part of the one that\u0027s already up there)","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"109c9aa3d733c5a6669f41751d5a042beb025319","unresolved":true,"context_lines":[{"line_number":458,"context_line":"            self.logger.info("},{"line_number":459,"context_line":"                \u0027processing %s unexpected task containers (e.g. %s) \u0027"},{"line_number":460,"context_line":"                \u0027if you have recently changed your expirer config \u0027"},{"line_number":461,"context_line":"                \u0027you can run swift-expirer-rebalancer.\u0027,"},{"line_number":462,"context_line":"                unexpected_task_containers[\u0027count\u0027],"},{"line_number":463,"context_line":"                \u0027 \u0027.join(unexpected_task_containers[\u0027examples\u0027]))"},{"line_number":464,"context_line":"        return container_list"}],"source_content_type":"text/x-python","patch_set":16,"id":"c1d74f48_ea6aa341","line":461,"updated":"2025-02-07 21:39:13.000000000","message":"Better as\n```\n                \u0027Processing %s unexpected task containers (e.g. %s). \u0027\n                \u0027If you have recently changed your expirer config \u0027\n                \u0027you can run swift-expirer-rebalancer to move tasks.\u0027,\n```","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ceb3b890f85812e6ca3217de5a176ee1d37ac138","unresolved":false,"context_lines":[{"line_number":458,"context_line":"            self.logger.info("},{"line_number":459,"context_line":"                \u0027processing %s unexpected task containers (e.g. %s) \u0027"},{"line_number":460,"context_line":"                \u0027if you have recently changed your expirer config \u0027"},{"line_number":461,"context_line":"                \u0027you can run swift-expirer-rebalancer.\u0027,"},{"line_number":462,"context_line":"                unexpected_task_containers[\u0027count\u0027],"},{"line_number":463,"context_line":"                \u0027 \u0027.join(unexpected_task_containers[\u0027examples\u0027]))"},{"line_number":464,"context_line":"        return container_list"}],"source_content_type":"text/x-python","patch_set":16,"id":"4f1b07ac_f9474449","line":461,"in_reply_to":"c1d74f48_ea6aa341","updated":"2025-02-11 03:32:52.000000000","message":"Done","commit_id":"1816eab89f90a02d8e40c9109a2802fcb3f17da4"}],"test/unit/cli/test_expirer_rebalancer.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0af0690936ef16c69504b67ee1f4e7b13531c4e5","unresolved":true,"context_lines":[{"line_number":287,"context_line":"                             args.logger.method_calls, \u0027with %r\u0027 % cli_args)"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":"    def test_process_task_containers(self):"},{"line_number":290,"context_line":"        random.seed(42)  # Fix the random seed for consistent behavior"},{"line_number":291,"context_line":"        now \u003d Timestamp.now()"},{"line_number":292,"context_line":"        num_stub_task_objs \u003d 32"},{"line_number":293,"context_line":"        task_container_to_obj_name_status \u003d defaultdict(list)"}],"source_content_type":"text/x-python","patch_set":5,"id":"d623aaba_866930a7","line":290,"updated":"2024-11-04 10:55:22.000000000","message":"it\u0027s not immediately obvious to me why this was necessary, because it seems like the expected task counts are calculated rather than hard-coded","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":287,"context_line":"                             args.logger.method_calls, \u0027with %r\u0027 % cli_args)"},{"line_number":288,"context_line":""},{"line_number":289,"context_line":"    def test_process_task_containers(self):"},{"line_number":290,"context_line":"        random.seed(42)  # Fix the random seed for consistent behavior"},{"line_number":291,"context_line":"        now \u003d Timestamp.now()"},{"line_number":292,"context_line":"        num_stub_task_objs \u003d 32"},{"line_number":293,"context_line":"        task_container_to_obj_name_status \u003d defaultdict(list)"}],"source_content_type":"text/x-python","patch_set":5,"id":"cea30c44_77f7ef48","line":290,"in_reply_to":"d623aaba_866930a7","updated":"2024-11-05 00:23:25.000000000","message":"Done","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0af0690936ef16c69504b67ee1f4e7b13531c4e5","unresolved":true,"context_lines":[{"line_number":288,"context_line":""},{"line_number":289,"context_line":"    def test_process_task_containers(self):"},{"line_number":290,"context_line":"        random.seed(42)  # Fix the random seed for consistent behavior"},{"line_number":291,"context_line":"        now \u003d Timestamp.now()"},{"line_number":292,"context_line":"        num_stub_task_objs \u003d 32"},{"line_number":293,"context_line":"        task_container_to_obj_name_status \u003d defaultdict(list)"},{"line_number":294,"context_line":"        for i in range(num_stub_task_objs):"}],"source_content_type":"text/x-python","patch_set":5,"id":"5374739c_896786f0","line":291,"updated":"2024-11-04 10:55:22.000000000","message":"the outcomes might be more predictable if time was fixed, both here and while the rebalancer runs, so the same task always fall into the same containers. But that\u0027s a little subtle. I think I\u0027d rather the task to container mapping was more deterministically \u0027wrong\u0027.","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":288,"context_line":""},{"line_number":289,"context_line":"    def test_process_task_containers(self):"},{"line_number":290,"context_line":"        random.seed(42)  # Fix the random seed for consistent behavior"},{"line_number":291,"context_line":"        now \u003d Timestamp.now()"},{"line_number":292,"context_line":"        num_stub_task_objs \u003d 32"},{"line_number":293,"context_line":"        task_container_to_obj_name_status \u003d defaultdict(list)"},{"line_number":294,"context_line":"        for i in range(num_stub_task_objs):"}],"source_content_type":"text/x-python","patch_set":5,"id":"e92ae002_c3f9dad1","line":291,"in_reply_to":"5374739c_896786f0","updated":"2024-11-05 00:23:25.000000000","message":"Done","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0af0690936ef16c69504b67ee1f4e7b13531c4e5","unresolved":true,"context_lines":[{"line_number":298,"context_line":"            else:"},{"line_number":299,"context_line":"                wrong_container \u003d False"},{"line_number":300,"context_line":"            task_container_name \u003d self.expirer_config.get_expirer_container("},{"line_number":301,"context_line":"                now, \u0027a\u0027, \u0027wrong-c\u0027 if wrong_container else \u0027c\u0027, obj_name)"},{"line_number":302,"context_line":"            task_container_to_obj_name_status[task_container_name].append("},{"line_number":303,"context_line":"                (obj_name, wrong_container))"},{"line_number":304,"context_line":"        stub_task_containers \u003d []"}],"source_content_type":"text/x-python","patch_set":5,"id":"971b6791_d161a861","line":301,"updated":"2024-11-04 10:55:22.000000000","message":"I spent some time trying to repro and debug the failing tests on zuul. Eventually I observed that some the wrongly placed tasks were considered correctly placed by the rebalancer, so I\u0027m not sure messing with the container name here is sufficient to guarantee \u0027wrongness\u0027.","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":298,"context_line":"            else:"},{"line_number":299,"context_line":"                wrong_container \u003d False"},{"line_number":300,"context_line":"            task_container_name \u003d self.expirer_config.get_expirer_container("},{"line_number":301,"context_line":"                now, \u0027a\u0027, \u0027wrong-c\u0027 if wrong_container else \u0027c\u0027, obj_name)"},{"line_number":302,"context_line":"            task_container_to_obj_name_status[task_container_name].append("},{"line_number":303,"context_line":"                (obj_name, wrong_container))"},{"line_number":304,"context_line":"        stub_task_containers \u003d []"}],"source_content_type":"text/x-python","patch_set":5,"id":"bb9a0975_e8e2ab8c","line":301,"in_reply_to":"971b6791_d161a861","updated":"2024-11-05 00:23:25.000000000","message":"with only 100 containers it\u0027s probably less than a 1/100 chance two paths hash to the same bucket - i wasn\u0027t sure how big of a problem it\u0027d turn out to be in practice, but it looks like it\u0027ll be necessary to fix so I came up with a helper that accounts for this possibility.","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c979f91820b58b2fe47c5750c9699d9f47ae0260","unresolved":false,"context_lines":[{"line_number":298,"context_line":"            else:"},{"line_number":299,"context_line":"                wrong_container \u003d False"},{"line_number":300,"context_line":"            task_container_name \u003d self.expirer_config.get_expirer_container("},{"line_number":301,"context_line":"                now, \u0027a\u0027, \u0027wrong-c\u0027 if wrong_container else \u0027c\u0027, obj_name)"},{"line_number":302,"context_line":"            task_container_to_obj_name_status[task_container_name].append("},{"line_number":303,"context_line":"                (obj_name, wrong_container))"},{"line_number":304,"context_line":"        stub_task_containers \u003d []"}],"source_content_type":"text/x-python","patch_set":5,"id":"0d97ae37_d384c76b","line":301,"in_reply_to":"bb9a0975_e8e2ab8c","updated":"2024-11-05 11:37:43.000000000","message":"1/100 chance that \u0027wrong_c/o\u0027 maps to the same container as \u0027c/o\u0027, but repeat that 32 times and it\u0027s ~1/3 likely to happen.\n\nThe workaround is sound - IIRC there\u0027s at least one other place in tests where we use a similar search-until-satisfied approach.","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0af0690936ef16c69504b67ee1f4e7b13531c4e5","unresolved":true,"context_lines":[{"line_number":604,"context_line":"                args, stub_task_containers, result_q)"},{"line_number":605,"context_line":""},{"line_number":606,"context_line":"        stats \u003d result_q.get()"},{"line_number":607,"context_line":"        # we let the first listing page; those entries should still get queued"},{"line_number":608,"context_line":"        expected_tasks \u003d num_stub_task_objs - len("},{"line_number":609,"context_line":"            task_container_to_obj_names["},{"line_number":610,"context_line":"                task_container_names[bad_container_index]"}],"source_content_type":"text/x-python","patch_set":5,"id":"c03c4538_0fb1d155","line":607,"range":{"start_line":607,"start_character":10,"end_line":607,"end_character":39},"updated":"2024-11-04 10:55:22.000000000","message":"is there a word missing here? maybe \u0027succeed\u0027 at the end of the phrase?","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":604,"context_line":"                args, stub_task_containers, result_q)"},{"line_number":605,"context_line":""},{"line_number":606,"context_line":"        stats \u003d result_q.get()"},{"line_number":607,"context_line":"        # we let the first listing page; those entries should still get queued"},{"line_number":608,"context_line":"        expected_tasks \u003d num_stub_task_objs - len("},{"line_number":609,"context_line":"            task_container_to_obj_names["},{"line_number":610,"context_line":"                task_container_names[bad_container_index]"}],"source_content_type":"text/x-python","patch_set":5,"id":"d2361cfe_79292e51","line":607,"range":{"start_line":607,"start_character":10,"end_line":607,"end_character":39},"in_reply_to":"c03c4538_0fb1d155","updated":"2024-11-05 00:23:25.000000000","message":"Done","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"0af0690936ef16c69504b67ee1f4e7b13531c4e5","unresolved":true,"context_lines":[{"line_number":608,"context_line":"        expected_tasks \u003d num_stub_task_objs - len("},{"line_number":609,"context_line":"            task_container_to_obj_names["},{"line_number":610,"context_line":"                task_container_names[bad_container_index]"},{"line_number":611,"context_line":"            ]) + 2"},{"line_number":612,"context_line":"        self.assertEqual({"},{"line_number":613,"context_line":"            \u0027processed_tasks\u0027: expected_tasks,"},{"line_number":614,"context_line":"            \u0027success_tasks\u0027: expected_tasks,"}],"source_content_type":"text/x-python","patch_set":5,"id":"326ee9cc_213fb49f","line":611,"range":{"start_line":611,"start_character":15,"end_line":611,"end_character":18},"updated":"2024-11-04 10:55:22.000000000","message":"it\u0027s possible (perhaps unlikely) that there will be less than 2 objects assigned to the bad container. It would be safer to use something like\n\n```\nmin(2, len(task_container_to_obj_names[task_container]))\n```","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":608,"context_line":"        expected_tasks \u003d num_stub_task_objs - len("},{"line_number":609,"context_line":"            task_container_to_obj_names["},{"line_number":610,"context_line":"                task_container_names[bad_container_index]"},{"line_number":611,"context_line":"            ]) + 2"},{"line_number":612,"context_line":"        self.assertEqual({"},{"line_number":613,"context_line":"            \u0027processed_tasks\u0027: expected_tasks,"},{"line_number":614,"context_line":"            \u0027success_tasks\u0027: expected_tasks,"}],"source_content_type":"text/x-python","patch_set":5,"id":"7e3efe6e_6136b6f0","line":611,"range":{"start_line":611,"start_character":15,"end_line":611,"end_character":18},"in_reply_to":"326ee9cc_213fb49f","updated":"2024-11-05 00:23:25.000000000","message":"I think \"bad\" in this context is the container listing that fails early; the 2 comes from the listing page split size - I\u0027ve now named the magic with a var at the top of the test.\n\nI think the issue with having \"wrong_container\" tasks not actually in the *wrong* container is a more general issue and I\u0027ve fixed that separately and I think it\u0027s easier than reasoning about \"well sometimes wrong is still right so this assertion is just a max/wrost-case\".","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c979f91820b58b2fe47c5750c9699d9f47ae0260","unresolved":false,"context_lines":[{"line_number":608,"context_line":"        expected_tasks \u003d num_stub_task_objs - len("},{"line_number":609,"context_line":"            task_container_to_obj_names["},{"line_number":610,"context_line":"                task_container_names[bad_container_index]"},{"line_number":611,"context_line":"            ]) + 2"},{"line_number":612,"context_line":"        self.assertEqual({"},{"line_number":613,"context_line":"            \u0027processed_tasks\u0027: expected_tasks,"},{"line_number":614,"context_line":"            \u0027success_tasks\u0027: expected_tasks,"}],"source_content_type":"text/x-python","patch_set":5,"id":"2602c40a_e7e2a298","line":611,"range":{"start_line":611,"start_character":15,"end_line":611,"end_character":18},"in_reply_to":"7e3efe6e_6136b6f0","updated":"2024-11-05 11:37:43.000000000","message":"the problem I was describing here is the one that is now checked at line 575.","commit_id":"cef25da04ca22bf55b80add0888350f72759a2cf"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"f2ce2cd613e51020c5250a5af03abd0679bda3f7","unresolved":true,"context_lines":[{"line_number":21,"context_line":"import shlex"},{"line_number":22,"context_line":"import time"},{"line_number":23,"context_line":"import unittest"},{"line_number":24,"context_line":"from unittest import mock"},{"line_number":25,"context_line":"from six.moves import cStringIO as StringIO"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"from swift.common.direct_client import DirectClientException"}],"source_content_type":"text/x-python","patch_set":6,"id":"cf3b1b3f_82814786","line":24,"updated":"2024-11-05 11:41:34.000000000","message":"we still need to just ``import mock`` for py27 😭","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"44eb8d872e023d3b4bb8d811e698c6debf78fd5c","unresolved":false,"context_lines":[{"line_number":21,"context_line":"import shlex"},{"line_number":22,"context_line":"import time"},{"line_number":23,"context_line":"import unittest"},{"line_number":24,"context_line":"from unittest import mock"},{"line_number":25,"context_line":"from six.moves import cStringIO as StringIO"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"from swift.common.direct_client import DirectClientException"}],"source_content_type":"text/x-python","patch_set":6,"id":"20b58905_ddab06f2","line":24,"in_reply_to":"cf3b1b3f_82814786","updated":"2024-11-05 22:51:12.000000000","message":"Done","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c979f91820b58b2fe47c5750c9699d9f47ae0260","unresolved":true,"context_lines":[{"line_number":287,"context_line":"            self.now, \u0027a\u0027, \u0027c\u0027, obj_name)"},{"line_number":288,"context_line":"        if wrong_container:"},{"line_number":289,"context_line":"            for i in range(10):"},{"line_number":290,"context_line":"                wrong_container \u003d self.expirer_config.get_expirer_container("},{"line_number":291,"context_line":"                    self.now, \u0027a\u0027, \u0027wrong-c%d\u0027 % i, obj_name)"},{"line_number":292,"context_line":"                if wrong_container !\u003d right_container:"},{"line_number":293,"context_line":"                    break"}],"source_content_type":"text/x-python","patch_set":6,"id":"85bed800_c7c8ecf2","line":290,"range":{"start_line":290,"start_character":16,"end_line":290,"end_character":31},"updated":"2024-11-05 11:37:43.000000000","message":"it works, but re-purposing \u0027wrong_container\u0027 from the bool flag to the result is confusing to me (when I look at the args vs the return value at first glance it looks like we\u0027re returning the bool)","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0c708f029f396d55c07ffb2ab3e6bb80629ddf6e","unresolved":false,"context_lines":[{"line_number":287,"context_line":"            self.now, \u0027a\u0027, \u0027c\u0027, obj_name)"},{"line_number":288,"context_line":"        if wrong_container:"},{"line_number":289,"context_line":"            for i in range(10):"},{"line_number":290,"context_line":"                wrong_container \u003d self.expirer_config.get_expirer_container("},{"line_number":291,"context_line":"                    self.now, \u0027a\u0027, \u0027wrong-c%d\u0027 % i, obj_name)"},{"line_number":292,"context_line":"                if wrong_container !\u003d right_container:"},{"line_number":293,"context_line":"                    break"}],"source_content_type":"text/x-python","patch_set":6,"id":"5fbcb837_2cee8ca6","line":290,"range":{"start_line":290,"start_character":16,"end_line":290,"end_character":31},"in_reply_to":"85bed800_c7c8ecf2","updated":"2024-11-05 15:41:01.000000000","message":"Acknowledged","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c979f91820b58b2fe47c5750c9699d9f47ae0260","unresolved":true,"context_lines":[{"line_number":406,"context_line":"                         task_container_to_obj_name_status)"},{"line_number":407,"context_line":""},{"line_number":408,"context_line":"    def test_process_q_moves_on(self):"},{"line_number":409,"context_line":"        now \u003d utils.Timestamp.now()"},{"line_number":410,"context_line":"        task_container_name \u003d self.get_expirer_container("},{"line_number":411,"context_line":"            \u0027o\u0027, wrong_container\u003dTrue)"},{"line_number":412,"context_line":"        num_stub_task_objs \u003d 8"}],"source_content_type":"text/x-python","patch_set":6,"id":"d9ae364b_3883a4a9","line":409,"updated":"2024-11-05 11:37:43.000000000","message":"self.now ?","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"44eb8d872e023d3b4bb8d811e698c6debf78fd5c","unresolved":false,"context_lines":[{"line_number":406,"context_line":"                         task_container_to_obj_name_status)"},{"line_number":407,"context_line":""},{"line_number":408,"context_line":"    def test_process_q_moves_on(self):"},{"line_number":409,"context_line":"        now \u003d utils.Timestamp.now()"},{"line_number":410,"context_line":"        task_container_name \u003d self.get_expirer_container("},{"line_number":411,"context_line":"            \u0027o\u0027, wrong_container\u003dTrue)"},{"line_number":412,"context_line":"        num_stub_task_objs \u003d 8"}],"source_content_type":"text/x-python","patch_set":6,"id":"3a3a4c8b_caa634e3","line":409,"in_reply_to":"d9ae364b_3883a4a9","updated":"2024-11-05 22:51:12.000000000","message":"Done","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"c979f91820b58b2fe47c5750c9699d9f47ae0260","unresolved":true,"context_lines":[{"line_number":572,"context_line":"        stub_task_containers \u003d []"},{"line_number":573,"context_line":"        for task_container in task_container_names:"},{"line_number":574,"context_line":"            obj_names \u003d task_container_to_obj_names[task_container]"},{"line_number":575,"context_line":"            self.assertGreater(len(obj_names), listing_page_split)  # sanity"},{"line_number":576,"context_line":"            stub_task_containers.append({"},{"line_number":577,"context_line":"                \"name\": task_container,"},{"line_number":578,"context_line":"                \"count\": len(obj_names),"}],"source_content_type":"text/x-python","patch_set":6,"id":"b96c0346_fd48d66b","line":575,"updated":"2024-11-05 11:37:43.000000000","message":"I see this fail ~ 1 in 50 times (measured over ~700 repeats)","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"0c708f029f396d55c07ffb2ab3e6bb80629ddf6e","unresolved":true,"context_lines":[{"line_number":572,"context_line":"        stub_task_containers \u003d []"},{"line_number":573,"context_line":"        for task_container in task_container_names:"},{"line_number":574,"context_line":"            obj_names \u003d task_container_to_obj_names[task_container]"},{"line_number":575,"context_line":"            self.assertGreater(len(obj_names), listing_page_split)  # sanity"},{"line_number":576,"context_line":"            stub_task_containers.append({"},{"line_number":577,"context_line":"                \"name\": task_container,"},{"line_number":578,"context_line":"                \"count\": len(obj_names),"}],"source_content_type":"text/x-python","patch_set":6,"id":"e79e09b2_b71f35b8","line":575,"in_reply_to":"b96c0346_fd48d66b","updated":"2024-11-05 15:41:01.000000000","message":"i\u0027m surprised it\u0027s that\u0027s bad!  glad I added the sanity 👍","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"44eb8d872e023d3b4bb8d811e698c6debf78fd5c","unresolved":false,"context_lines":[{"line_number":572,"context_line":"        stub_task_containers \u003d []"},{"line_number":573,"context_line":"        for task_container in task_container_names:"},{"line_number":574,"context_line":"            obj_names \u003d task_container_to_obj_names[task_container]"},{"line_number":575,"context_line":"            self.assertGreater(len(obj_names), listing_page_split)  # sanity"},{"line_number":576,"context_line":"            stub_task_containers.append({"},{"line_number":577,"context_line":"                \"name\": task_container,"},{"line_number":578,"context_line":"                \"count\": len(obj_names),"}],"source_content_type":"text/x-python","patch_set":6,"id":"de146921_e156bc10","line":575,"in_reply_to":"e79e09b2_b71f35b8","updated":"2024-11-05 22:51:12.000000000","message":"Done","commit_id":"36bf7141ead73626e8281e3f4ff989f875cb5565"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"40fbb605830a6acf73ecbc8c87dcef161965cfa3","unresolved":true,"context_lines":[{"line_number":657,"context_line":"        }, stats)"},{"line_number":658,"context_line":""},{"line_number":659,"context_line":"        self.assertEqual(["},{"line_number":660,"context_line":"            \u0027%(prefix)s %(prefix)s error listing tasks in %(task_container)s: \u0027 % {"},{"line_number":661,"context_line":"                \u0027prefix\u0027: expirer_rebalancer._get_worker_prefix(),"},{"line_number":662,"context_line":"                \u0027task_container\u0027: stub_task_containers[bad_container_index],"},{"line_number":663,"context_line":"            }"}],"source_content_type":"text/x-python","patch_set":11,"id":"19fd7205_918a344e","line":660,"updated":"2024-11-15 23:00:50.000000000","message":"I am not sure why I need another ``%(prefix)s`` to pass this test, could be related to this?\n\nhttps://review.opendev.org/c/openstack/swift/+/931060/comment/a52ae6b0_9e9ad44d/","commit_id":"958848719b8b1b3587431a4698474675eedb5f4d"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"914f404eb803d9bb5c5a96f7c353024b2e809f10","unresolved":false,"context_lines":[{"line_number":657,"context_line":"        }, stats)"},{"line_number":658,"context_line":""},{"line_number":659,"context_line":"        self.assertEqual(["},{"line_number":660,"context_line":"            \u0027%(prefix)s %(prefix)s error listing tasks in %(task_container)s: \u0027 % {"},{"line_number":661,"context_line":"                \u0027prefix\u0027: expirer_rebalancer._get_worker_prefix(),"},{"line_number":662,"context_line":"                \u0027task_container\u0027: stub_task_containers[bad_container_index],"},{"line_number":663,"context_line":"            }"}],"source_content_type":"text/x-python","patch_set":11,"id":"25669878_376a1658","line":660,"in_reply_to":"09f9c360_e33e1273","updated":"2024-11-18 19:08:42.000000000","message":"Acknowledged","commit_id":"958848719b8b1b3587431a4698474675eedb5f4d"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"e48a6628f70b80a7d6fe710b6cbd8923542a9be2","unresolved":true,"context_lines":[{"line_number":657,"context_line":"        }, stats)"},{"line_number":658,"context_line":""},{"line_number":659,"context_line":"        self.assertEqual(["},{"line_number":660,"context_line":"            \u0027%(prefix)s %(prefix)s error listing tasks in %(task_container)s: \u0027 % {"},{"line_number":661,"context_line":"                \u0027prefix\u0027: expirer_rebalancer._get_worker_prefix(),"},{"line_number":662,"context_line":"                \u0027task_container\u0027: stub_task_containers[bad_container_index],"},{"line_number":663,"context_line":"            }"}],"source_content_type":"text/x-python","patch_set":11,"id":"09f9c360_e33e1273","line":660,"in_reply_to":"19fd7205_918a344e","updated":"2024-11-18 11:22:37.000000000","message":"This is a bug in the recently modified SwiftLogAdapter, I have a fix proposed here https://review.opendev.org/c/openstack/swift/+/935501","commit_id":"958848719b8b1b3587431a4698474675eedb5f4d"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c62d4ea2bec7ffae69a9ec340f5e7e1dd10740d7","unresolved":true,"context_lines":[{"line_number":108,"context_line":"        args.logger \u003d self.logger"},{"line_number":109,"context_line":"        return args"},{"line_number":110,"context_line":""},{"line_number":111,"context_line":"    def _run_move_task_object(self, obj, resp, args_str\u003d\u0027\u0027):"},{"line_number":112,"context_line":"        target_task_container \u003d self.expirer_config.get_expirer_container("},{"line_number":113,"context_line":"            self.now, \u0027a\u0027, \u0027c\u0027, obj)"},{"line_number":114,"context_line":"        orig_task_container \u003d self.expirer_config.get_expirer_container("}],"source_content_type":"text/x-python","patch_set":19,"id":"f4933ae5_18a8df34","line":111,"updated":"2025-02-11 22:16:24.000000000","message":"added a new test helper function, then most of similar test cases can reuse it.","commit_id":"09fb235eda7bf70a642856137c6a9009fa0c0055"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"c62d4ea2bec7ffae69a9ec340f5e7e1dd10740d7","unresolved":true,"context_lines":[{"line_number":198,"context_line":"        with mocked_http_conn(*resp) as conn, \\"},{"line_number":199,"context_line":"             mock.patch.object(expirer_rebalancer.eventlet, \u0027sleep\u0027), \\"},{"line_number":200,"context_line":"             self.assertRaises(Exception) as ctx:"},{"line_number":201,"context_line":"            worker._move_task_object(target_task_container, orig_task_info)"},{"line_number":202,"context_line":"        self.assertEqual([\u0027PUT\u0027] * 6,"},{"line_number":203,"context_line":"                         [r[\u0027method\u0027] for r in conn.requests])"},{"line_number":204,"context_line":"        msg \u003d str(ctx.exception)"}],"source_content_type":"text/x-python","patch_set":19,"id":"0cb2a6af_cfe422be","line":201,"updated":"2025-02-11 22:16:24.000000000","message":"this test case uses ``_move_task_object`` directly, so I skipped it for reusing of the new test helper function ``_run_move_task_object``","commit_id":"09fb235eda7bf70a642856137c6a9009fa0c0055"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2b20e46fb23e6c76910b5ddfc7e2fd25da1569ab","unresolved":true,"context_lines":[{"line_number":740,"context_line":""},{"line_number":741,"context_line":"        self.assertEqual(1, ret)"},{"line_number":742,"context_line":"        self.assertEqual(\u0027done with errors, please check logs.\\n\u0027,"},{"line_number":743,"context_line":"                         mock_stdout.getvalue())"},{"line_number":744,"context_line":""},{"line_number":745,"context_line":"    def test_main(self):"},{"line_number":746,"context_line":"        # attempting to test main to sanity check config/parser handling might"}],"source_content_type":"text/x-python","patch_set":20,"id":"21427099_f4be4e71","line":743,"updated":"2025-04-11 09:54:12.000000000","message":"this fails on my VSAIO with\n\n```\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d FAILURES \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n________________________________________________________ TestExpirerRebalance.test_main_return_on_errors ________________________________________________________\n\nself \u003d \u003ctest.unit.cli.test_expirer_rebalancer.TestExpirerRebalance testMethod\u003dtest_main_return_on_errors\u003e\n\n    def test_main_return_on_errors(self):\n        conf_path \u003d os.path.join(self.testdir, \u0027object-expirer.conf\u0027)\n        with open(conf_path, \u0027w\u0027) as fd:\n            fd.write(\u0027[object-expirer]\u0027)\n\n        with mock.patch(\u0027sys.stdout\u0027, new\u003dStringIO()) as mock_stdout, \\\n            mock.patch.object(expirer_rebalancer.ExpirerRebalancer,\n                              \u0027get_task_containers_to_migrate\u0027) as mock_get:\n            mock_get.side_effect \u003d Exception(\u0027test error\u0027)\n            ret \u003d expirer_rebalancer.main([conf_path])\n\n        self.assertEqual(1, ret)\n        self.assertEqual(\u0027done with errors, please check logs.\\n\u0027,\n                         mock_stdout.getvalue())\n\n        with mock.patch(\u0027sys.stdout\u0027, new\u003dStringIO()) as mock_stdout, \\\n            mock.patch.object(expirer_rebalancer.ExpirerRebalancer,\n                              \u0027run_workers\u0027) as mock_run_workers:\n            mock_run_workers.return_value \u003d {\u0027failed_tasks\u0027: 1}\n            ret \u003d expirer_rebalancer.main([conf_path])\n\n        self.assertEqual(1, ret)\n\u003e       self.assertEqual(\u0027done with errors, please check logs.\\n\u0027,\n                         mock_stdout.getvalue())\nE       AssertionError: \u0027done with errors, please check logs.\\n\u0027 !\u003d \u0027failed_tasks 1\\ndone with errors, please check logs.\\n\u0027\nE       + failed_tasks 1\nE         done with errors, please check logs.\n\ntest/unit/cli/test_expirer_rebalancer.py:742: AssertionError\n```\n\nIt seems like it *should* fail because I *expected* stdout to also container ``failed_tasks\u0027 1`` as per line 406 in ``expirer_rebalancer.py``.\n\nI dropped in a debug_logger to see what was going on. I think the problem is that when ``/etc/swift/internal-client.conf`` does NOT exist then the call to ``get_task_containers_to_migrate`` blows up an we\u0027re actually seeing the first error handler in ``main`` i.e. the test is not actually callin ``run_workers``.\n\nOn my VSAIO ``/etc/swift/internal-client.conf`` DOES exists so main proceeds to ``run_workers`` and the test fails because the test assertion is wrong.\n\nTo confirm, I can make the test fail (in different ways) with or without ``/etc/swift/internal-client.conf`` by adding:\n\n```\ndiff --git a/test/unit/cli/test_expirer_rebalancer.py b/test/unit/cli/test_expirer_rebalancer.py\nindex 136f8dab1..3d8002968 100644\n--- a/test/unit/cli/test_expirer_rebalancer.py\n+++ b/test/unit/cli/test_expirer_rebalancer.py\n@@ -739,6 +739,7 @@ class TestExpirerRebalance(unittest.TestCase):\n             ret \u003d expirer_rebalancer.main([conf_path])\n\n         self.assertEqual(1, ret)\n+        self.assertTrue(mock_run_workers.call_args_list)\n         self.assertEqual(\u0027done with errors, please check logs.\\n\u0027,\n                          mock_stdout.getvalue())\n```\n\nSo I think some more mocking is required to make the test agnostic w.r.t. ``/etc/swift/internal-client.conf``.","commit_id":"3df47bbc917b2464b6ad2c05632945ce4e4a5037"}],"test/unit/proxy/controllers/test_obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"281381d987650152c84d7e3720d36bd6a7149795","unresolved":true,"context_lines":[{"line_number":2649,"context_line":"                         found_host_device)"},{"line_number":2650,"context_line":""},{"line_number":2651,"context_line":"    def test_POST_delete_at_configure_task_container_per_day(self):"},{"line_number":2652,"context_line":"        self.conf[\u0027expiring_objects_task_container_per_day\u0027] \u003d 1"},{"line_number":2653,"context_line":"        self._make_app()"},{"line_number":2654,"context_line":"        self.assertEqual(1, self.app.expirer_config.task_container_per_day)"},{"line_number":2655,"context_line":"        t \u003d str(int(time.time() + 100))"}],"source_content_type":"text/x-python","patch_set":4,"id":"6e337e44_809788d2","line":2652,"updated":"2024-11-01 21:50:06.000000000","message":"idk, maybe this test would look better in the deprecate change that introduces the expirer config to the proxy - it doesn\u0027t seem to say much at this point that the proxy is using the expirer_config (which now happens to support configuring task_container_per_day)","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"2b6600ba12fe57889fdfcc11ca0a784906cab07a","unresolved":true,"context_lines":[{"line_number":2649,"context_line":"                         found_host_device)"},{"line_number":2650,"context_line":""},{"line_number":2651,"context_line":"    def test_POST_delete_at_configure_task_container_per_day(self):"},{"line_number":2652,"context_line":"        self.conf[\u0027expiring_objects_task_container_per_day\u0027] \u003d 1"},{"line_number":2653,"context_line":"        self._make_app()"},{"line_number":2654,"context_line":"        self.assertEqual(1, self.app.expirer_config.task_container_per_day)"},{"line_number":2655,"context_line":"        t \u003d str(int(time.time() + 100))"}],"source_content_type":"text/x-python","patch_set":4,"id":"92eb1ca9_f1df7e83","line":2652,"in_reply_to":"6e337e44_809788d2","updated":"2024-11-04 00:44:11.000000000","message":"agreed. but nothing wrong to add a new test for it in the follow-up patch though.","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":2649,"context_line":"                         found_host_device)"},{"line_number":2650,"context_line":""},{"line_number":2651,"context_line":"    def test_POST_delete_at_configure_task_container_per_day(self):"},{"line_number":2652,"context_line":"        self.conf[\u0027expiring_objects_task_container_per_day\u0027] \u003d 1"},{"line_number":2653,"context_line":"        self._make_app()"},{"line_number":2654,"context_line":"        self.assertEqual(1, self.app.expirer_config.task_container_per_day)"},{"line_number":2655,"context_line":"        t \u003d str(int(time.time() + 100))"}],"source_content_type":"text/x-python","patch_set":4,"id":"17eaa536_f23ef4ff","line":2652,"in_reply_to":"92eb1ca9_f1df7e83","updated":"2024-11-05 00:23:25.000000000","message":"Acknowledged","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"281381d987650152c84d7e3720d36bd6a7149795","unresolved":true,"context_lines":[{"line_number":2650,"context_line":""},{"line_number":2651,"context_line":"    def test_POST_delete_at_configure_task_container_per_day(self):"},{"line_number":2652,"context_line":"        self.conf[\u0027expiring_objects_task_container_per_day\u0027] \u003d 1"},{"line_number":2653,"context_line":"        self._make_app()"},{"line_number":2654,"context_line":"        self.assertEqual(1, self.app.expirer_config.task_container_per_day)"},{"line_number":2655,"context_line":"        t \u003d str(int(time.time() + 100))"},{"line_number":2656,"context_line":"        expected_part, expected_nodes, expected_delete_at_container \u003d \\"}],"source_content_type":"text/x-python","patch_set":4,"id":"227fbad6_188a89c6","line":2653,"updated":"2024-11-01 21:50:06.000000000","message":"oh look, this uses `_make_app`","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"143957295999f5bf2d1a198f57de5e2f351ecc49","unresolved":false,"context_lines":[{"line_number":2650,"context_line":""},{"line_number":2651,"context_line":"    def test_POST_delete_at_configure_task_container_per_day(self):"},{"line_number":2652,"context_line":"        self.conf[\u0027expiring_objects_task_container_per_day\u0027] \u003d 1"},{"line_number":2653,"context_line":"        self._make_app()"},{"line_number":2654,"context_line":"        self.assertEqual(1, self.app.expirer_config.task_container_per_day)"},{"line_number":2655,"context_line":"        t \u003d str(int(time.time() + 100))"},{"line_number":2656,"context_line":"        expected_part, expected_nodes, expected_delete_at_container \u003d \\"}],"source_content_type":"text/x-python","patch_set":4,"id":"85a4208b_1b096bd9","line":2653,"in_reply_to":"227fbad6_188a89c6","updated":"2024-11-05 00:23:25.000000000","message":"Done","commit_id":"5e5bbf98bd4e51b5333cd3b97715422b25aea9cd"}]}
