)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8dfae3988058cc3097fcb66292c873c85d85fdfe","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"c5ff9da9_b8c8629e","updated":"2023-04-14 22:07:04.000000000","message":"I think maybe some more tests to enumerate the variety of values we send down to the backend.  I think a simple boolean might be better in someways.\n\nDo we ever have sharding_state \u003d shrunk in memcache?","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"49c35e221e9470db497d5d964911f00a573e7242","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"a5f6de71_777639c6","updated":"2023-04-19 23:34:37.000000000","message":"Thanks for the review Clay, food for thought. I\u0027m replied inline.","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"729add9ea40f7effc44a467507db372a490fa02b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"e7d3255c_2b8e3060","updated":"2023-05-17 16:19:54.000000000","message":"matt \u0026 al convinced me that it\u0027s ok to send sharding/sharded or whatever state we get out of memcache down to the object layer.\n\nI do still wonder if there may be some way to keep all the state machine logic for the various states consolidated into one place.","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"49c35e221e9470db497d5d964911f00a573e7242","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"9abb9f7e_b86e10ac","in_reply_to":"c5ff9da9_b8c8629e","updated":"2023-04-19 23:34:37.000000000","message":"not yet, but who knows, maybe we\u0027ll do funky things once we actually support shrinking :P","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"1b5b29839d921d0f9010c928ef1f854633d0a23e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"59f404d8_5b161c9f","updated":"2023-05-23 07:25:36.000000000","message":"@jianjian there is some object async update probe tests so will add something there. Good suggestion. Will have a new patch up soon.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"8ffa5740_0c360242","updated":"2023-05-22 19:43:00.000000000","message":"I think my only nit is inconsistency with container_path, db_state vs db_state, container_path - and I don\u0027t really care which way it goes.  Maybe the test_updater unittests would be worth making more explicit with less magic in the fake.  I\u0027m still struggling to get a feel for the complete enumeration of db_state values we can pull out of cache.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f2d560d126a35178489533f4fe1026f3965ca2ae","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"1e0f4c78_33a6de3f","updated":"2023-05-22 21:27:51.000000000","message":"another thought about information loss","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"00847b561410942b182c38df4d3cdee556b12042","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"8ae91b03_009ac16a","updated":"2024-01-24 19:01:58.000000000","message":"On the -1, in no particular order:\n\n- I like Jian\u0027s suggestions for the probe tests.\n- I think I\u0027d prefer `X-Root-Container-Db-State` for the header name.\n- The `test_updater.py` changes seem like they should come in [the updater patch](https://review.opendev.org/c/openstack/swift/+/874721). (Though we\u0027ll still want to have some discussion about whether/how to improve the fake.)\n- The repetition of the default state across `_get_update_target`, `POST`, `PUT`, and `DELETE` seems unfortunate, especially since three of those all use the other one.\n\nIs this useful without the follow-up to the updater? Are we planning on updating our sync-counting/categorization script or something?","commit_id":"c898adde9495e5e390c70d60ac78bc5c122748e1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d8c270170dc506fc0b80dd8b449be8f8c1f81df2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"37c30c2b_213d7bb2","updated":"2024-02-02 00:42:07.000000000","message":"Yeah, I can get behind this! Are we planning on updating any of our out-of-tree tooling, too, or is this all about enabling the updater to use memcache?","commit_id":"a71ff9949bef97990f0dfbeaecba15523dc8812a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"503f6ec205fcd5d435a64065737583430f602129","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"6fdca719_5bd414fc","updated":"2024-02-02 22:15:43.000000000","message":"OK, looks like that might be a legit flakey test 😞","commit_id":"5ea38013b9586c1bcb97e380ff747d67e9516a38"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f85a311d98cb5c15af697f57481f31011341be8b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"d549a9c2_654b4102","updated":"2024-02-02 22:52:21.000000000","message":"Oh man, the more I pull at this, the more trouble I see in probe tests. I think I\u0027ve got a fix inbound, though!","commit_id":"5ea38013b9586c1bcb97e380ff747d67e9516a38"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"76e0e96fc4b9c3c27be66137a4e39b135eb6ee68","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"7c840e93_c0576c19","updated":"2024-02-02 05:00:25.000000000","message":"Yeah, yeah -- pep8, still good.\n\nSmall things still identified:\n\n- Maybe move delete-at stuff into _backend_requests, too\n- Maybe make signatures more consistent\n- Maybe get some metrics on when we hit the not-great state where we have container info in cache, so we know we\u0027re sharded, but we don\u0027t have shard ranges in cache and making the backend request to populate cache fails\n\n... but I think all of those could be proposed as follow-ups if we actually care.\n\nMain question on my mind before a +A is whether this will be useful on its own (if only with some out-of-tree operator tooling), or really kinda requires the updater change.","commit_id":"5ea38013b9586c1bcb97e380ff747d67e9516a38"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"7f816dc45b6ab087d46a3b59275f1dec50cacfee","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"01e777c0_8a5478c4","updated":"2024-02-02 03:24:54.000000000","message":"ops pep8 issue. I thought I had run tox -epy39,pep8 before pushing, but mustive forgot :shrug:","commit_id":"5ea38013b9586c1bcb97e380ff747d67e9516a38"},{"author":{"_account_id":34892,"name":"ASHWIN A NAIR","display_name":"indianwhocodes","email":"nairashwin952013@gmail.com","username":"indianwhocodes","status":"Nvidia"},"change_message_id":"b7d723faf6ce9797a7423934d7084d5a31c519dc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"65078d12_9a108f84","updated":"2024-05-03 18:14:22.000000000","message":"recheck","commit_id":"eaed0d3e73a0ad0a5ee5e3299c2448c332fb3d66"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":16,"id":"3f6e28f0_e75c91e0","updated":"2024-07-13 02:22:10.000000000","message":"I don\u0027t think there\u0027s anything materially necessary going on in here:\n\n924108: WIP: add missing tests for _get_update_target | https://review.opendev.org/c/openstack/swift/+/924108\n\nThe probe tests are really awesome!  Since the proxy change just sends along w/e from cache, and the object server doesn\u0027t *do* anything with db_state yet (except put it in the async pending) the probe tests *functionally* validates pretty much everything the change claims to do.\n\nThe drive-by refactoring is a sensible imporovement IMHO.\n\nI had to push up a couple of (very) minor fixups to tests, only leaving off +A to hear from Zuul.","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b756ed925c28f037601609fd1c67a3f2a7676dca","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":17,"id":"766ad2cb_ed905370","updated":"2024-07-15 13:07:51.000000000","message":"Only good stuff here!  Maybe some stuff could be better, but this is already great and only makes improvements *easier*\n\n924108: trivial: refactor _get_update_target | https://review.opendev.org/c/openstack/swift/+/924108","commit_id":"e8affa7db5817e50cd82130a8f4c250725b80884"}],"swift/obj/server.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":true,"context_lines":[{"line_number":276,"context_line":"    def async_update(self, op, account, container, obj, host, partition,"},{"line_number":277,"context_line":"                     contdevice, headers_out, objdevice, policy,"},{"line_number":278,"context_line":"                     logger_thread_locals\u003dNone, container_path\u003dNone,"},{"line_number":279,"context_line":"                     db_state\u003dNone):"},{"line_number":280,"context_line":"        \"\"\""},{"line_number":281,"context_line":"        Sends or saves an async update."},{"line_number":282,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"4324f70e_cee3f6a8","line":279,"updated":"2023-05-22 19:43:00.000000000","message":"this signature update uses container_path, db_state","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":276,"context_line":"    def async_update(self, op, account, container, obj, host, partition,"},{"line_number":277,"context_line":"                     contdevice, headers_out, objdevice, policy,"},{"line_number":278,"context_line":"                     logger_thread_locals\u003dNone, container_path\u003dNone,"},{"line_number":279,"context_line":"                     db_state\u003dNone):"},{"line_number":280,"context_line":"        \"\"\""},{"line_number":281,"context_line":"        Sends or saves an async update."},{"line_number":282,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"46bb2e48_ea82230d","line":279,"in_reply_to":"4324f70e_cee3f6a8","updated":"2024-07-13 02:22:10.000000000","message":"Acknowledged","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"00847b561410942b182c38df4d3cdee556b12042","unresolved":true,"context_lines":[{"line_number":379,"context_line":"        contdevices \u003d [d.strip() for d in"},{"line_number":380,"context_line":"                       headers_in.get(\u0027X-Container-Device\u0027, \u0027\u0027).split(\u0027,\u0027)]"},{"line_number":381,"context_line":"        contpartition \u003d headers_in.get(\u0027X-Container-Partition\u0027, \u0027\u0027)"},{"line_number":382,"context_line":"        contdbstate \u003d headers_in.get(\u0027X-Container-Db-State\u0027, \u0027\u0027)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"        if len(conthosts) !\u003d len(contdevices):"},{"line_number":385,"context_line":"            # This shouldn\u0027t happen unless there\u0027s a bug in the proxy,"}],"source_content_type":"text/x-python","patch_set":7,"id":"ac30f044_8aef8996","line":382,"updated":"2024-01-24 19:01:58.000000000","message":"Should this default to blank, on `None`? If blank here, should we make that the default for `async_update`, too?","commit_id":"c898adde9495e5e390c70d60ac78bc5c122748e1"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"64e57382a13a66c2651148fffce6f3ca4a9ce130","unresolved":false,"context_lines":[{"line_number":379,"context_line":"        contdevices \u003d [d.strip() for d in"},{"line_number":380,"context_line":"                       headers_in.get(\u0027X-Container-Device\u0027, \u0027\u0027).split(\u0027,\u0027)]"},{"line_number":381,"context_line":"        contpartition \u003d headers_in.get(\u0027X-Container-Partition\u0027, \u0027\u0027)"},{"line_number":382,"context_line":"        contdbstate \u003d headers_in.get(\u0027X-Container-Db-State\u0027, \u0027\u0027)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"        if len(conthosts) !\u003d len(contdevices):"},{"line_number":385,"context_line":"            # This shouldn\u0027t happen unless there\u0027s a bug in the proxy,"}],"source_content_type":"text/x-python","patch_set":7,"id":"49c4e90a_6df05726","line":382,"in_reply_to":"ac30f044_8aef8996","updated":"2024-02-02 00:06:16.000000000","message":"yeah, this should probably be None.","commit_id":"c898adde9495e5e390c70d60ac78bc5c122748e1"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8dfae3988058cc3097fcb66292c873c85d85fdfe","unresolved":true,"context_lines":[{"line_number":396,"context_line":"    def _get_update_target(self, req, container_info):"},{"line_number":397,"context_line":"        # find the sharded container to which we\u0027ll send the update"},{"line_number":398,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":399,"context_line":"        if db_state in (\u0027sharded\u0027, \u0027sharding\u0027):"},{"line_number":400,"context_line":"            shard_range \u003d self._get_update_shard("},{"line_number":401,"context_line":"                req, self.account_name, self.container_name, self.object_name)"},{"line_number":402,"context_line":"            if shard_range:"}],"source_content_type":"text/x-python","patch_set":3,"id":"58b60a76_ddca27a0","line":399,"updated":"2023-04-14 22:07:04.000000000","message":"i worry about passing a \"sharded\" vs \"sharding\" state instead of *just* is_sharded\n\nI don\u0027t think sharded containers will become unsharded but sharding will quickly become sharded\n\ncould we just infer is_sharded based on the shard_range.name/None?","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"49c35e221e9470db497d5d964911f00a573e7242","unresolved":true,"context_lines":[{"line_number":396,"context_line":"    def _get_update_target(self, req, container_info):"},{"line_number":397,"context_line":"        # find the sharded container to which we\u0027ll send the update"},{"line_number":398,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":399,"context_line":"        if db_state in (\u0027sharded\u0027, \u0027sharding\u0027):"},{"line_number":400,"context_line":"            shard_range \u003d self._get_update_shard("},{"line_number":401,"context_line":"                req, self.account_name, self.container_name, self.object_name)"},{"line_number":402,"context_line":"            if shard_range:"}],"source_content_type":"text/x-python","patch_set":3,"id":"f0011f63_0defa2be","line":399,"in_reply_to":"58b60a76_ddca27a0","updated":"2023-04-19 23:34:37.000000000","message":"Well that\u0027s what kinda got us into this bind, we fill in the container-path, which is basically the shard path to update. The account and container are always looking at the root.\nWhen we can\u0027t talk to the root, we fail to get the shard, so the container-path ends up being None.. we currently interprit this as unsharded.. so will go back to the root.\n\nHowever, if we pass the db_state we get 2 things:\n1. We have this on hand already in the proxy, it\u0027s what made us want to go grab the shard from root in the first place, so we\u0027d know if its sharded/unsharded even if we fail to get the shard path.\n2. Passing in the db_state rather then is_sharded means we have that peice of metadata incase it ever is important to know the state, maybe shrinking will be something we care about (although I guess we wouldn\u0027t get that from the root, but collapsed \u003d\u003d unsharded).\n\nI figure its better to store the actual state rather then a meta state (bool with less info) incase future us ever kick our past selves :P\n\nAlthough, I could be convinced to change it to is_sharded if someone really wants to twist my arm :)","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":false,"context_lines":[{"line_number":396,"context_line":"    def _get_update_target(self, req, container_info):"},{"line_number":397,"context_line":"        # find the sharded container to which we\u0027ll send the update"},{"line_number":398,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":399,"context_line":"        if db_state in (\u0027sharded\u0027, \u0027sharding\u0027):"},{"line_number":400,"context_line":"            shard_range \u003d self._get_update_shard("},{"line_number":401,"context_line":"                req, self.account_name, self.container_name, self.object_name)"},{"line_number":402,"context_line":"            if shard_range:"}],"source_content_type":"text/x-python","patch_set":3,"id":"cd606e8d_5b12e434","line":399,"in_reply_to":"f0011f63_0defa2be","updated":"2023-05-22 19:43:00.000000000","message":"Done","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8dfae3988058cc3097fcb66292c873c85d85fdfe","unresolved":true,"context_lines":[{"line_number":405,"context_line":"                return partition, nodes, db_state, shard_range.name"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"        return (container_info[\u0027partition\u0027], container_info[\u0027nodes\u0027],"},{"line_number":408,"context_line":"                db_state, None)"},{"line_number":409,"context_line":""},{"line_number":410,"context_line":"    @public"},{"line_number":411,"context_line":"    @cors_validation"}],"source_content_type":"text/x-python","patch_set":3,"id":"051f210c_96278c82","line":408,"updated":"2023-04-14 22:07:04.000000000","message":"the 3rd value for unsharded is always ... None, or.. 4the value now i guess","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"49c35e221e9470db497d5d964911f00a573e7242","unresolved":true,"context_lines":[{"line_number":405,"context_line":"                return partition, nodes, db_state, shard_range.name"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"        return (container_info[\u0027partition\u0027], container_info[\u0027nodes\u0027],"},{"line_number":408,"context_line":"                db_state, None)"},{"line_number":409,"context_line":""},{"line_number":410,"context_line":"    @public"},{"line_number":411,"context_line":"    @cors_validation"}],"source_content_type":"text/x-python","patch_set":3,"id":"32b8fee1_7ab83e8f","line":408,"in_reply_to":"051f210c_96278c82","updated":"2023-04-19 23:34:37.000000000","message":"oh you mean we could infer from the shard_range.name rather then pass back the db_state.. that\u0027s true too.. That would simplify the return tuple, but only if we decide to send back some meta is_sharded rather then the full db_state (see my response above).","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":false,"context_lines":[{"line_number":405,"context_line":"                return partition, nodes, db_state, shard_range.name"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"        return (container_info[\u0027partition\u0027], container_info[\u0027nodes\u0027],"},{"line_number":408,"context_line":"                db_state, None)"},{"line_number":409,"context_line":""},{"line_number":410,"context_line":"    @public"},{"line_number":411,"context_line":"    @cors_validation"}],"source_content_type":"text/x-python","patch_set":3,"id":"ded117db_a463ce49","line":408,"in_reply_to":"32b8fee1_7ab83e8f","updated":"2023-05-22 19:43:00.000000000","message":"Done","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8dfae3988058cc3097fcb66292c873c85d85fdfe","unresolved":true,"context_lines":[{"line_number":466,"context_line":"                \u0027%(ip)s:%(port)s\u0027 % container)"},{"line_number":467,"context_line":"            headers[index][\u0027X-Container-Device\u0027] \u003d csv_append("},{"line_number":468,"context_line":"                headers[index].get(\u0027X-Container-Device\u0027),"},{"line_number":469,"context_line":"                container[\u0027device\u0027])"},{"line_number":470,"context_line":"            headers[index][\u0027X-Container-Db-State\u0027] \u003d db_state"},{"line_number":471,"context_line":"            if container_path:"},{"line_number":472,"context_line":"                headers[index][\u0027X-Backend-Quoted-Container-Path\u0027] \u003d quote("}],"source_content_type":"text/x-python","patch_set":3,"id":"b441ac3f_a36eddc5","line":469,"updated":"2023-04-14 22:07:04.000000000","message":"I\u0027m sure we have proxy tests that assert these x-container-device headers, I think we should update them to ensure the new x-container-db-state headers are sent to the backend as well.","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"49c35e221e9470db497d5d964911f00a573e7242","unresolved":true,"context_lines":[{"line_number":466,"context_line":"                \u0027%(ip)s:%(port)s\u0027 % container)"},{"line_number":467,"context_line":"            headers[index][\u0027X-Container-Device\u0027] \u003d csv_append("},{"line_number":468,"context_line":"                headers[index].get(\u0027X-Container-Device\u0027),"},{"line_number":469,"context_line":"                container[\u0027device\u0027])"},{"line_number":470,"context_line":"            headers[index][\u0027X-Container-Db-State\u0027] \u003d db_state"},{"line_number":471,"context_line":"            if container_path:"},{"line_number":472,"context_line":"                headers[index][\u0027X-Backend-Quoted-Container-Path\u0027] \u003d quote("}],"source_content_type":"text/x-python","patch_set":3,"id":"be5099a2_de0d6981","line":469,"in_reply_to":"b441ac3f_a36eddc5","updated":"2023-04-19 23:34:37.000000000","message":"hmm, I thought I did that already... although maybe I didn\u0027t and only planned too, been off on vactaion so maybe I\u0027m just mis-remembering :P\n\nwill take a look!","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":false,"context_lines":[{"line_number":466,"context_line":"                \u0027%(ip)s:%(port)s\u0027 % container)"},{"line_number":467,"context_line":"            headers[index][\u0027X-Container-Device\u0027] \u003d csv_append("},{"line_number":468,"context_line":"                headers[index].get(\u0027X-Container-Device\u0027),"},{"line_number":469,"context_line":"                container[\u0027device\u0027])"},{"line_number":470,"context_line":"            headers[index][\u0027X-Container-Db-State\u0027] \u003d db_state"},{"line_number":471,"context_line":"            if container_path:"},{"line_number":472,"context_line":"                headers[index][\u0027X-Backend-Quoted-Container-Path\u0027] \u003d quote("}],"source_content_type":"text/x-python","patch_set":3,"id":"1ad4305f_8f290051","line":469,"in_reply_to":"be5099a2_de0d6981","updated":"2023-05-22 19:43:00.000000000","message":"Done","commit_id":"5e791c4f8a6ef044cfbb35bea95af0003eb0c210"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":true,"context_lines":[{"line_number":405,"context_line":"                return partition, nodes, shard_range.name"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"        return (container_info[\u0027partition\u0027], container_info[\u0027nodes\u0027],"},{"line_number":408,"context_line":"                None)"},{"line_number":409,"context_line":""},{"line_number":410,"context_line":"    @public"},{"line_number":411,"context_line":"    @cors_validation"}],"source_content_type":"text/x-python","patch_set":4,"id":"21f7e368_b9bdbfab","line":408,"updated":"2023-05-22 19:43:00.000000000","message":"this change seems somewhat unrelated now","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"db63e260e775cf6ff00a6c7fb0b8e6d6d2f11a85","unresolved":false,"context_lines":[{"line_number":405,"context_line":"                return partition, nodes, shard_range.name"},{"line_number":406,"context_line":""},{"line_number":407,"context_line":"        return (container_info[\u0027partition\u0027], container_info[\u0027nodes\u0027],"},{"line_number":408,"context_line":"                None)"},{"line_number":409,"context_line":""},{"line_number":410,"context_line":"    @public"},{"line_number":411,"context_line":"    @cors_validation"}],"source_content_type":"text/x-python","patch_set":4,"id":"1a225a0b_3925af1b","line":408,"in_reply_to":"21f7e368_b9bdbfab","updated":"2023-05-23 04:06:34.000000000","message":"yup, good point.\n\nFixed","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":true,"context_lines":[{"line_number":442,"context_line":"            req.headers[\u0027X-Backend-Next-Part-Power\u0027] \u003d next_part_power"},{"line_number":443,"context_line":"        partition, nodes \u003d obj_ring.get_nodes("},{"line_number":444,"context_line":"            self.account_name, self.container_name, self.object_name)"},{"line_number":445,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"        headers \u003d self._backend_requests("},{"line_number":448,"context_line":"            req, len(nodes), container_partition, container_nodes,"}],"source_content_type":"text/x-python","patch_set":4,"id":"cca2c0f1_6decbaed","line":445,"updated":"2023-05-22 19:43:00.000000000","message":"this is at least as clear as plumbing through _get_update_target (which already takes container_info)","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"db63e260e775cf6ff00a6c7fb0b8e6d6d2f11a85","unresolved":true,"context_lines":[{"line_number":442,"context_line":"            req.headers[\u0027X-Backend-Next-Part-Power\u0027] \u003d next_part_power"},{"line_number":443,"context_line":"        partition, nodes \u003d obj_ring.get_nodes("},{"line_number":444,"context_line":"            self.account_name, self.container_name, self.object_name)"},{"line_number":445,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"        headers \u003d self._backend_requests("},{"line_number":448,"context_line":"            req, len(nodes), container_partition, container_nodes,"}],"source_content_type":"text/x-python","patch_set":4,"id":"e14a43f7_2c916d02","line":445,"in_reply_to":"098c7275_8d522b19","updated":"2023-05-23 04:06:34.000000000","message":"what is the didn\u0027t get cache so treat it as unsharded? There could be a window where we got the container info out of cache, great. I guess it could be out of date. Or we went back to the backend to get the info. If we go to the backend and get a success then we have the db_state. If we don\u0027t get a success, then we would\u0027ve returned a 404 back at line 425.\n\nIf it\u0027s failing to get the shardrange, then we at least have an info in the state of sharding or sharded, which is valid.\n\nMaybe having a default here (line 445) is confusing and useless seeing as we get the container_info to unsharded by default when we go get the container_info elsewhere, at least from my reading the code. I guess defaulting here is more of a belts and braces thing.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"f2d560d126a35178489533f4fe1026f3965ca2ae","unresolved":true,"context_lines":[{"line_number":442,"context_line":"            req.headers[\u0027X-Backend-Next-Part-Power\u0027] \u003d next_part_power"},{"line_number":443,"context_line":"        partition, nodes \u003d obj_ring.get_nodes("},{"line_number":444,"context_line":"            self.account_name, self.container_name, self.object_name)"},{"line_number":445,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"        headers \u003d self._backend_requests("},{"line_number":448,"context_line":"            req, len(nodes), container_partition, container_nodes,"}],"source_content_type":"text/x-python","patch_set":4,"id":"098c7275_8d522b19","line":445,"in_reply_to":"cca2c0f1_6decbaed","updated":"2023-05-22 21:27:51.000000000","message":"I wonder if we should differentiate between \"got cache and it said unsharded\" from \"didn\u0027t get cache, so treat it like it\u0027s unsharded\"\n\nmaybe \"unknown\" would be a better value that None?  It seems like unsharded containers\u0027 info already say explicitly sharded_state \u003d unsharded","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":442,"context_line":"            req.headers[\u0027X-Backend-Next-Part-Power\u0027] \u003d next_part_power"},{"line_number":443,"context_line":"        partition, nodes \u003d obj_ring.get_nodes("},{"line_number":444,"context_line":"            self.account_name, self.container_name, self.object_name)"},{"line_number":445,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":446,"context_line":""},{"line_number":447,"context_line":"        headers \u003d self._backend_requests("},{"line_number":448,"context_line":"            req, len(nodes), container_partition, container_nodes,"}],"source_content_type":"text/x-python","patch_set":4,"id":"d2877c0f_0167e9d1","line":445,"in_reply_to":"e14a43f7_2c916d02","updated":"2024-07-13 02:22:10.000000000","message":"yeah I\u0027m not really sure what I was thinking here, it seems like we always have `container_info[\u0027sharding_state\u0027]` even in tests:\n\n```\n\u003e\u003e\u003e data \u003d memcached.MemcacheRing([\u0027127.0.0.1\u0027], logger\u003dget_logger({})).get(get_cache_key(\u0027AUTH_test\u0027, \u0027doc\u0027))\n\u003e\u003e\u003e print(json.dumps(data, indent\u003d2))\n{\n  \"status\": 204,\n  \"read_acl\": \".r:*,.rlistings\",\n  \"write_acl\": null,\n  \"sync_to\": null,\n  \"sync_key\": null,\n  \"object_count\": \"501\",\n  \"bytes\": \"41772759\",\n  \"versions\": null,\n  \"storage_policy\": \"0\",\n  \"cors\": {\n    \"allow_origin\": null,\n    \"expose_headers\": null,\n    \"max_age\": null\n  },\n  \"meta\": {\n    \"web-index\": \"index.html\"\n  },\n  \"sysmeta\": {},\n  \"sharding_state\": \"unsharded\",\n  \"created_at\": \"1720646542.68942\",\n  \"put_timestamp\": \"1720646544.87301\",\n  \"delete_timestamp\": \"0000000000.00000\",\n  \"status_changed_at\": \"1720646542.66907\"\n}\n```","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":true,"context_lines":[{"line_number":454,"context_line":"                          container_partition, containers,"},{"line_number":455,"context_line":"                          delete_at_container\u003dNone, delete_at_partition\u003dNone,"},{"line_number":456,"context_line":"                          delete_at_nodes\u003dNone, db_state\u003dNone,"},{"line_number":457,"context_line":"                          container_path\u003dNone):"},{"line_number":458,"context_line":"        policy_index \u003d req.headers[\u0027X-Backend-Storage-Policy-Index\u0027]"},{"line_number":459,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":460,"context_line":"        headers \u003d [self.generate_request_headers(req, additional\u003dreq.headers)"}],"source_content_type":"text/x-python","patch_set":4,"id":"fb338baa_799a628f","line":457,"updated":"2023-05-22 19:43:00.000000000","message":"this signature update uses db_state, container_path","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":454,"context_line":"                          container_partition, containers,"},{"line_number":455,"context_line":"                          delete_at_container\u003dNone, delete_at_partition\u003dNone,"},{"line_number":456,"context_line":"                          delete_at_nodes\u003dNone, db_state\u003dNone,"},{"line_number":457,"context_line":"                          container_path\u003dNone):"},{"line_number":458,"context_line":"        policy_index \u003d req.headers[\u0027X-Backend-Storage-Policy-Index\u0027]"},{"line_number":459,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":460,"context_line":"        headers \u003d [self.generate_request_headers(req, additional\u003dreq.headers)"}],"source_content_type":"text/x-python","patch_set":4,"id":"e806a9c2_7c2d8125","line":457,"in_reply_to":"7d5014e0_205b5abb","updated":"2024-07-13 02:22:10.000000000","message":"Tim gets me, but irrelevant now that we pass in container_info - which is nice.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"00847b561410942b182c38df4d3cdee556b12042","unresolved":true,"context_lines":[{"line_number":454,"context_line":"                          container_partition, containers,"},{"line_number":455,"context_line":"                          delete_at_container\u003dNone, delete_at_partition\u003dNone,"},{"line_number":456,"context_line":"                          delete_at_nodes\u003dNone, db_state\u003dNone,"},{"line_number":457,"context_line":"                          container_path\u003dNone):"},{"line_number":458,"context_line":"        policy_index \u003d req.headers[\u0027X-Backend-Storage-Policy-Index\u0027]"},{"line_number":459,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":460,"context_line":"        headers \u003d [self.generate_request_headers(req, additional\u003dreq.headers)"}],"source_content_type":"text/x-python","patch_set":4,"id":"7d5014e0_205b5abb","line":457,"in_reply_to":"a9353dbc_3ddcb054","updated":"2024-01-24 19:01:58.000000000","message":"I think Clay was more just noting that it\u0027s a little odd, the juxtaposition of this signature change that of `async_update`. IDK that it really matters, though -- and I *do* think that we should feel free to change these signatures as we see fit. I find it hard to believe that any 3rd party would be calling them.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"db63e260e775cf6ff00a6c7fb0b8e6d6d2f11a85","unresolved":true,"context_lines":[{"line_number":454,"context_line":"                          container_partition, containers,"},{"line_number":455,"context_line":"                          delete_at_container\u003dNone, delete_at_partition\u003dNone,"},{"line_number":456,"context_line":"                          delete_at_nodes\u003dNone, db_state\u003dNone,"},{"line_number":457,"context_line":"                          container_path\u003dNone):"},{"line_number":458,"context_line":"        policy_index \u003d req.headers[\u0027X-Backend-Storage-Policy-Index\u0027]"},{"line_number":459,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":460,"context_line":"        headers \u003d [self.generate_request_headers(req, additional\u003dreq.headers)"}],"source_content_type":"text/x-python","patch_set":4,"id":"a9353dbc_3ddcb054","line":457,"in_reply_to":"fb338baa_799a628f","updated":"2023-05-23 04:06:34.000000000","message":"yeah, maybe I should append db_state to the end, but when calling, for some reason I didn\u0027t want to kwarg it (though I can\u0027t remember why, maybe because we always had it on hand). But can change the order if thats important.\n\nAnother option could be to just update the container_parition and containers in the container_info (which we already have, but _get_update_target is leaving them point to the root) and instead just pass the info itself into _backend_requests. Then we can just pull all the data we need out of the info dict.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":true,"context_lines":[{"line_number":967,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":968,"context_line":"        headers \u003d self._backend_requests("},{"line_number":969,"context_line":"            req, node_count, container_partition, container_nodes,"},{"line_number":970,"context_line":"            db_state\u003ddb_state, container_path\u003dcontainer_path)"},{"line_number":971,"context_line":"        return self._delete_object(req, obj_ring, partition, headers,"},{"line_number":972,"context_line":"                                   node_count\u003dnode_count,"},{"line_number":973,"context_line":"                                   node_iterator\u003dnode_iterator)"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff735b90_00a0c10b","line":970,"updated":"2023-05-22 19:43:00.000000000","message":"there\u0027s some sort of overlapping pattern in these methods with self.container_info/self._get_update_target/self._backend_request\n\n... but I can\u0027t see anything obviously better than the obvious solution of updating all the _backend_requests call sites like you\u0027ve done in this change.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":967,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":968,"context_line":"        headers \u003d self._backend_requests("},{"line_number":969,"context_line":"            req, node_count, container_partition, container_nodes,"},{"line_number":970,"context_line":"            db_state\u003ddb_state, container_path\u003dcontainer_path)"},{"line_number":971,"context_line":"        return self._delete_object(req, obj_ring, partition, headers,"},{"line_number":972,"context_line":"                                   node_count\u003dnode_count,"},{"line_number":973,"context_line":"                                   node_iterator\u003dnode_iterator)"}],"source_content_type":"text/x-python","patch_set":4,"id":"341cc799_5dd78e73","line":970,"in_reply_to":"554da2d0_a83c413d","updated":"2024-07-13 02:22:10.000000000","message":"agreed, it\u0027s wonky we stick ring information in container_info - I think _get_update_target is trying to offer an abstraction around that but kind of leaky.  \n\nThe solution you found to pass container_info into _backend_requets is a nice improvement and quite possibly the clever idea I was trying to find but could not see.  KUDOS!","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"db63e260e775cf6ff00a6c7fb0b8e6d6d2f11a85","unresolved":true,"context_lines":[{"line_number":967,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":968,"context_line":"        headers \u003d self._backend_requests("},{"line_number":969,"context_line":"            req, node_count, container_partition, container_nodes,"},{"line_number":970,"context_line":"            db_state\u003ddb_state, container_path\u003dcontainer_path)"},{"line_number":971,"context_line":"        return self._delete_object(req, obj_ring, partition, headers,"},{"line_number":972,"context_line":"                                   node_count\u003dnode_count,"},{"line_number":973,"context_line":"                                   node_iterator\u003dnode_iterator)"}],"source_content_type":"text/x-python","patch_set":4,"id":"554da2d0_a83c413d","line":970,"in_reply_to":"ff735b90_00a0c10b","updated":"2023-05-23 04:06:34.000000000","message":"yeah, I had thought about trying to unite them some more.\nLike I mentioned above we actually put the container_partition and container_nodes into the container info, but that always points to the root and we don\u0027t update those in _get_update_target.. we could just update in the container_info and maybe even add a container_path and simplify the _backend_requests to take in a container_info dict.. as that might simplify the _backend_requests signature but that just overloads the container_info dict more, so also not ideal.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"00847b561410942b182c38df4d3cdee556b12042","unresolved":true,"context_lines":[{"line_number":399,"context_line":"        if db_state in (\u0027sharded\u0027, \u0027sharding\u0027):"},{"line_number":400,"context_line":"            shard_range \u003d self._get_update_shard("},{"line_number":401,"context_line":"                req, self.account_name, self.container_name, self.object_name)"},{"line_number":402,"context_line":"            if shard_range:"},{"line_number":403,"context_line":"                partition, nodes \u003d self.app.container_ring.get_nodes("},{"line_number":404,"context_line":"                    shard_range.account, shard_range.container)"},{"line_number":405,"context_line":"                return partition, nodes, shard_range.name"}],"source_content_type":"text/x-python","patch_set":6,"id":"971159df_04e8c430","line":402,"updated":"2024-01-24 19:01:58.000000000","message":"All this plumbing is mainly about trying to deal with a failure here, right? We could get `db_state` and it\u0027s `sharded` or `sharding`, but then we *couldn\u0027t* get the destination shard. So we want to be able to clue in the updater to the fact that we\u0027re probably going to need to redirect.\n\nMakes me think we ought to emit a metric here. I suppose we *already know* it happens sometimes (container info is still in cache, but updating shard ranges falls out) and we already know what happens next (asyncs pile up, root DB gets overloaded, it becomes harder to keep *either* container info or shard ranges in cache) -- but it\u0027d maybe still be useful?\n\nIt *also* makes me wonder if we should maybe start pushing back harder on clients when we\u0027re in this situation -- how crazy would it really be for us to 503 or something here?","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":399,"context_line":"        if db_state in (\u0027sharded\u0027, \u0027sharding\u0027):"},{"line_number":400,"context_line":"            shard_range \u003d self._get_update_shard("},{"line_number":401,"context_line":"                req, self.account_name, self.container_name, self.object_name)"},{"line_number":402,"context_line":"            if shard_range:"},{"line_number":403,"context_line":"                partition, nodes \u003d self.app.container_ring.get_nodes("},{"line_number":404,"context_line":"                    shard_range.account, shard_range.container)"},{"line_number":405,"context_line":"                return partition, nodes, shard_range.name"}],"source_content_type":"text/x-python","patch_set":6,"id":"124db750_1883898e","line":402,"in_reply_to":"971159df_04e8c430","updated":"2024-07-13 02:22:10.000000000","message":"\u003e Makes me think we ought to emit a metric here\n\nReasonable question, but after consideration - I think not?  The metric will quite soon be reasonably approximate to \"creating an async on purpose\" - so, like you said: \"it\u0027s not like we won\u0027t know when this is happening.\"  And I think the existing shard_update_cache.miss.\u003cstatus\u003e metrics already give us even MORE information than we could emit here.\n\n\u003e how crazy would it really be for us to 503 or something here\n\nI think that would be pretty crazy given all the work we\u0027ve done to allow async updates to container(shards) and explicity trade eventual consistency for high-availibility.  I think for db sharding in particular we\u0027re going to have a very hard time ever rejecting writes when listing servers are overloaded; but maybe with some more sophisticated understanding of an \"error budget\" and our consistency windows we could eventually trade off against \"can we afford some errors/backoff depending on how out of sync are we willing to get temporarily\".","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"00847b561410942b182c38df4d3cdee556b12042","unresolved":true,"context_lines":[{"line_number":467,"context_line":"            headers[index][\u0027X-Container-Device\u0027] \u003d csv_append("},{"line_number":468,"context_line":"                headers[index].get(\u0027X-Container-Device\u0027),"},{"line_number":469,"context_line":"                container[\u0027device\u0027])"},{"line_number":470,"context_line":"            headers[index][\u0027X-Container-Db-State\u0027] \u003d db_state"},{"line_number":471,"context_line":"            if container_path:"},{"line_number":472,"context_line":"                headers[index][\u0027X-Backend-Quoted-Container-Path\u0027] \u003d quote("},{"line_number":473,"context_line":"                    container_path)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3955f76d_390c2b23","line":470,"updated":"2024-01-24 19:01:58.000000000","message":"OK, so even if we\u0027ve got a `container_path` (so, we\u0027re targeting the update at a shard, not the root), the `db_state` will be for the root. Should we maybe make that more clear in the header name? All the *other* headers we set here will be swapped over to pertain to the shard, right?","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d8c270170dc506fc0b80dd8b449be8f8c1f81df2","unresolved":false,"context_lines":[{"line_number":467,"context_line":"            headers[index][\u0027X-Container-Device\u0027] \u003d csv_append("},{"line_number":468,"context_line":"                headers[index].get(\u0027X-Container-Device\u0027),"},{"line_number":469,"context_line":"                container[\u0027device\u0027])"},{"line_number":470,"context_line":"            headers[index][\u0027X-Container-Db-State\u0027] \u003d db_state"},{"line_number":471,"context_line":"            if container_path:"},{"line_number":472,"context_line":"                headers[index][\u0027X-Backend-Quoted-Container-Path\u0027] \u003d quote("},{"line_number":473,"context_line":"                    container_path)"}],"source_content_type":"text/x-python","patch_set":6,"id":"2d32081f_a7309444","line":470,"in_reply_to":"3955f76d_390c2b23","updated":"2024-02-02 00:42:07.000000000","message":"Done","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"00847b561410942b182c38df4d3cdee556b12042","unresolved":true,"context_lines":[{"line_number":879,"context_line":"                return aresp"},{"line_number":880,"context_line":""},{"line_number":881,"context_line":"        if not container_nodes:"},{"line_number":882,"context_line":"            return HTTPNotFound(request\u003dreq)"},{"line_number":883,"context_line":""},{"line_number":884,"context_line":"        # update content type in case it is missing"},{"line_number":885,"context_line":"        self._update_content_type(req)"}],"source_content_type":"text/x-python","patch_set":6,"id":"3fc6ee0d_60dff32e","line":882,"updated":"2024-01-24 19:01:58.000000000","message":"Ok, similar to Matt\u0027s explanation above, this is where we\u0027ll bail if we didn\u0027t get a successful/useful `container_info`.","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d8c270170dc506fc0b80dd8b449be8f8c1f81df2","unresolved":false,"context_lines":[{"line_number":879,"context_line":"                return aresp"},{"line_number":880,"context_line":""},{"line_number":881,"context_line":"        if not container_nodes:"},{"line_number":882,"context_line":"            return HTTPNotFound(request\u003dreq)"},{"line_number":883,"context_line":""},{"line_number":884,"context_line":"        # update content type in case it is missing"},{"line_number":885,"context_line":"        self._update_content_type(req)"}],"source_content_type":"text/x-python","patch_set":6,"id":"9e513d15_43b017b7","line":882,"in_reply_to":"3fc6ee0d_60dff32e","updated":"2024-02-02 00:42:07.000000000","message":"Acknowledged","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"00847b561410942b182c38df4d3cdee556b12042","unresolved":true,"context_lines":[{"line_number":941,"context_line":"            if aresp:"},{"line_number":942,"context_line":"                return aresp"},{"line_number":943,"context_line":"        if not container_nodes:"},{"line_number":944,"context_line":"            return HTTPNotFound(request\u003dreq)"},{"line_number":945,"context_line":"        partition, nodes \u003d obj_ring.get_nodes("},{"line_number":946,"context_line":"            self.account_name, self.container_name, self.object_name)"},{"line_number":947,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"e7a09715_eae25012","line":944,"updated":"2024-01-24 19:01:58.000000000","message":"Off-topic: I don\u0027t really like our flow for these -- `if not container_nodes` seems to obscure *why* we\u0027re returning 404 -- I\u0027m not convinced that it\u0027s different from `if not is_success(container_info.get(\u0027status\u0027))`, but the latter makes it much more obvious why (IMO).","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d8c270170dc506fc0b80dd8b449be8f8c1f81df2","unresolved":true,"context_lines":[{"line_number":941,"context_line":"            if aresp:"},{"line_number":942,"context_line":"                return aresp"},{"line_number":943,"context_line":"        if not container_nodes:"},{"line_number":944,"context_line":"            return HTTPNotFound(request\u003dreq)"},{"line_number":945,"context_line":"        partition, nodes \u003d obj_ring.get_nodes("},{"line_number":946,"context_line":"            self.account_name, self.container_name, self.object_name)"},{"line_number":947,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"727e26f9_581bc2e6","line":944,"in_reply_to":"073bf8e6_35ed6e26","updated":"2024-02-02 00:42:07.000000000","message":"Maybe there was some pathological case when\n\n* you\u0027ve got a tiny cluster,\n* container_info _is_ in cache, but\n* all container nodes are error limited\n\n? But it\u0027s not at all clear to me that we _should_ 404 at that point -- 503 _might_ be reasonable, but we also seem to have enough info at hand to just service the request... I think I like this better, thanks.","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"081644230370a835def65f9537d1943cf77a40ed","unresolved":false,"context_lines":[{"line_number":941,"context_line":"            if aresp:"},{"line_number":942,"context_line":"                return aresp"},{"line_number":943,"context_line":"        if not container_nodes:"},{"line_number":944,"context_line":"            return HTTPNotFound(request\u003dreq)"},{"line_number":945,"context_line":"        partition, nodes \u003d obj_ring.get_nodes("},{"line_number":946,"context_line":"            self.account_name, self.container_name, self.object_name)"},{"line_number":947,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"bdbd4f1e_6f4bc9bf","line":944,"in_reply_to":"727e26f9_581bc2e6","updated":"2024-06-21 22:35:11.000000000","message":"Done","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"64e57382a13a66c2651148fffce6f3ca4a9ce130","unresolved":true,"context_lines":[{"line_number":941,"context_line":"            if aresp:"},{"line_number":942,"context_line":"                return aresp"},{"line_number":943,"context_line":"        if not container_nodes:"},{"line_number":944,"context_line":"            return HTTPNotFound(request\u003dreq)"},{"line_number":945,"context_line":"        partition, nodes \u003d obj_ring.get_nodes("},{"line_number":946,"context_line":"            self.account_name, self.container_name, self.object_name)"},{"line_number":947,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"073bf8e6_35ed6e26","line":944,"in_reply_to":"e7a09715_eae25012","updated":"2024-02-02 00:06:16.000000000","message":"You right, re set container_nodes to None `if not is_success(info.get(\u0027status\u0027))` so it\u0027s the same thing.\n\nI think the point was if we don\u0027t have containers to update we fail the request.","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"00847b561410942b182c38df4d3cdee556b12042","unresolved":true,"context_lines":[{"line_number":963,"context_line":"                obj_ring, partition, req, policy\u003dpolicy,"},{"line_number":964,"context_line":"                local_handoffs_first\u003dTrue)"},{"line_number":965,"context_line":""},{"line_number":966,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":967,"context_line":"        headers \u003d self._backend_requests("},{"line_number":968,"context_line":"            req, node_count, container_partition, container_nodes,"},{"line_number":969,"context_line":"            db_state\u003ddb_state, container_path\u003dcontainer_path)"}],"source_content_type":"text/x-python","patch_set":6,"id":"c6f83008_c2c0f462","line":966,"updated":"2024-01-24 19:01:58.000000000","message":"Would it be better to have `_get_update_target` start returning `db_state` since it\u0027s already got it in hand anyway? I don\u0027t like how many times we have to repeat this default value -- especially since it seems like we [already ensure it\u0027s set](https://github.com/openstack/swift/blob/2.31.1/swift/proxy/controllers/base.py#L498-L499) for any successful info returned.","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d8c270170dc506fc0b80dd8b449be8f8c1f81df2","unresolved":false,"context_lines":[{"line_number":963,"context_line":"                obj_ring, partition, req, policy\u003dpolicy,"},{"line_number":964,"context_line":"                local_handoffs_first\u003dTrue)"},{"line_number":965,"context_line":""},{"line_number":966,"context_line":"        db_state \u003d container_info.get(\u0027sharding_state\u0027, \u0027unsharded\u0027)"},{"line_number":967,"context_line":"        headers \u003d self._backend_requests("},{"line_number":968,"context_line":"            req, node_count, container_partition, container_nodes,"},{"line_number":969,"context_line":"            db_state\u003ddb_state, container_path\u003dcontainer_path)"}],"source_content_type":"text/x-python","patch_set":6,"id":"7ec555fd_2f203868","line":966,"in_reply_to":"c6f83008_c2c0f462","updated":"2024-02-02 00:42:07.000000000","message":"Done","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d8c270170dc506fc0b80dd8b449be8f8c1f81df2","unresolved":true,"context_lines":[{"line_number":438,"context_line":"        policy_index \u003d req.headers[\u0027X-Backend-Storage-Policy-Index\u0027]"},{"line_number":439,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":440,"context_line":"        container_partition, containers, container_path, db_state \u003d \\"},{"line_number":441,"context_line":"            self._get_update_target(req, container_info)"},{"line_number":442,"context_line":"        headers \u003d [self.generate_request_headers(req, additional\u003dreq.headers)"},{"line_number":443,"context_line":"                   for _junk in range(n_outgoing)]"},{"line_number":444,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"b08a29c5_5c070255","line":441,"updated":"2024-02-02 00:42:07.000000000","message":"Ooh, I hadn\u0027t been thinking about pushing this all of this down to `_backend_requests`... I think I rather like it!\n\nShould we do the same with the `x-delete-at` stuff? Presumably, guarded with an `if req.method in (\u0027PUT\u0027, \u0027POST\u0027):`","commit_id":"a71ff9949bef97990f0dfbeaecba15523dc8812a"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3cd765529239dc0f251989ddedd9b1443dccf0c7","unresolved":true,"context_lines":[{"line_number":438,"context_line":"        policy_index \u003d req.headers[\u0027X-Backend-Storage-Policy-Index\u0027]"},{"line_number":439,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":440,"context_line":"        container_partition, containers, container_path, db_state \u003d \\"},{"line_number":441,"context_line":"            self._get_update_target(req, container_info)"},{"line_number":442,"context_line":"        headers \u003d [self.generate_request_headers(req, additional\u003dreq.headers)"},{"line_number":443,"context_line":"                   for _junk in range(n_outgoing)]"},{"line_number":444,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"ec5466c0_dd0fc316","line":441,"in_reply_to":"b08a29c5_5c070255","updated":"2024-02-05 05:27:42.000000000","message":"oh yeah, so long as it\u0027s garded. Yeah I don\u0027t see why we can\u0027t. Maybe I\u0027ll make a follow on patch for that for now.","commit_id":"a71ff9949bef97990f0dfbeaecba15523dc8812a"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"081644230370a835def65f9537d1943cf77a40ed","unresolved":false,"context_lines":[{"line_number":438,"context_line":"        policy_index \u003d req.headers[\u0027X-Backend-Storage-Policy-Index\u0027]"},{"line_number":439,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":440,"context_line":"        container_partition, containers, container_path, db_state \u003d \\"},{"line_number":441,"context_line":"            self._get_update_target(req, container_info)"},{"line_number":442,"context_line":"        headers \u003d [self.generate_request_headers(req, additional\u003dreq.headers)"},{"line_number":443,"context_line":"                   for _junk in range(n_outgoing)]"},{"line_number":444,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"0b09807e_ff874887","line":441,"in_reply_to":"ec5466c0_dd0fc316","updated":"2024-06-21 22:35:11.000000000","message":"Acknowledged","commit_id":"a71ff9949bef97990f0dfbeaecba15523dc8812a"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":419,"context_line":"        req.ensure_x_timestamp()"},{"line_number":420,"context_line":""},{"line_number":421,"context_line":"        req, delete_at_container, delete_at_part, \\"},{"line_number":422,"context_line":"            delete_at_nodes \u003d self._config_obj_expiration(req)"},{"line_number":423,"context_line":""},{"line_number":424,"context_line":"        # pass the policy index to storage nodes via req header"},{"line_number":425,"context_line":"        policy_index \u003d req.headers.get(\u0027X-Backend-Storage-Policy-Index\u0027,"}],"source_content_type":"text/x-python","patch_set":16,"id":"546c4272_e8d293a7","line":422,"updated":"2024-07-13 02:22:10.000000000","message":"same logic as PUT","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":439,"context_line":""},{"line_number":440,"context_line":"    def _backend_requests(self, req, n_outgoing,"},{"line_number":441,"context_line":"                          container_info, delete_at_container\u003dNone,"},{"line_number":442,"context_line":"                          delete_at_partition\u003dNone, delete_at_nodes\u003dNone):"},{"line_number":443,"context_line":"        policy_index \u003d req.headers[\u0027X-Backend-Storage-Policy-Index\u0027]"},{"line_number":444,"context_line":"        policy \u003d POLICIES.get_by_index(policy_index)"},{"line_number":445,"context_line":"        container_partition, containers, container_path, db_state \u003d \\"}],"source_content_type":"text/x-python","patch_set":16,"id":"f6f38c36_566f1588","line":442,"updated":"2024-07-13 02:22:10.000000000","message":"the signature change from `(container_partition, containers)` \u003d\u003e `container_info` is a non-trivial refactoring that could be done independently to annotating backend requested headers based on the values in container_info.  I like the new signature, but it does make the individualized delete_at params seems strange.\n\nBut ultimately this diff is only 40 lines, *adds* functionality and still manages a negative line count!?  That\u0027s like multiple good things; I\u0027m not complaining.","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":889,"context_line":""},{"line_number":890,"context_line":"        # check if object is set to be automatically deleted (i.e. expired)"},{"line_number":891,"context_line":"        req, delete_at_container, delete_at_part, \\"},{"line_number":892,"context_line":"            delete_at_nodes \u003d self._config_obj_expiration(req)"},{"line_number":893,"context_line":""},{"line_number":894,"context_line":"        # add special headers to be handled by storage nodes"},{"line_number":895,"context_line":"        outgoing_headers \u003d self._backend_requests("}],"source_content_type":"text/x-python","patch_set":16,"id":"359a94de_db330738","line":892,"updated":"2024-07-13 02:22:10.000000000","message":"we already pass the request object into _backend_headers - any particular advantage to leave this duplicated here and in POST as opposed to burying it along with container_info in `_backend_requests`?","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":923,"context_line":"            aresp \u003d req.environ[\u0027swift.authorize\u0027](req)"},{"line_number":924,"context_line":"            if aresp:"},{"line_number":925,"context_line":"                return aresp"},{"line_number":926,"context_line":"        if not is_success(container_info.get(\u0027status\u0027)):"},{"line_number":927,"context_line":"            return HTTPNotFound(request\u003dreq)"},{"line_number":928,"context_line":"        partition, nodes \u003d obj_ring.get_nodes("},{"line_number":929,"context_line":"            self.account_name, self.container_name, self.object_name)"}],"source_content_type":"text/x-python","patch_set":16,"id":"a74b8901_41b5fd0e","line":926,"updated":"2024-07-13 02:22:10.000000000","message":"I think this is actually more obvious than `if not container_nodes` but is again mostly related to the refactoring and not stated goal in the commit message.","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"}],"test/probe/common.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"65f460a4d945dd68fa25e6e1789f71279207e2bd","unresolved":true,"context_lines":[{"line_number":555,"context_line":"        for policy in ENABLED_POLICIES:"},{"line_number":556,"context_line":"            for dev in policy.object_ring.devs:"},{"line_number":557,"context_line":"                all_obj_nodes[dev[\u0027device\u0027]] \u003d dev"},{"line_number":558,"context_line":"        return list(all_obj_nodes.values())"},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"    def gather_async_pendings(self, onodes\u003dNone):"},{"line_number":561,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"2a727146_0b7cbe2a","line":558,"updated":"2024-02-02 23:02:49.000000000","message":"Previously always slightly busted on py3!","commit_id":"cf1508af905b3ba3d2e55d01551e312d235107ce"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"081644230370a835def65f9537d1943cf77a40ed","unresolved":false,"context_lines":[{"line_number":555,"context_line":"        for policy in ENABLED_POLICIES:"},{"line_number":556,"context_line":"            for dev in policy.object_ring.devs:"},{"line_number":557,"context_line":"                all_obj_nodes[dev[\u0027device\u0027]] \u003d dev"},{"line_number":558,"context_line":"        return list(all_obj_nodes.values())"},{"line_number":559,"context_line":""},{"line_number":560,"context_line":"    def gather_async_pendings(self, onodes\u003dNone):"},{"line_number":561,"context_line":"        \"\"\""}],"source_content_type":"text/x-python","patch_set":10,"id":"b0834f33_d0a80107","line":558,"in_reply_to":"2a727146_0b7cbe2a","updated":"2024-06-21 22:35:11.000000000","message":"Acknowledged","commit_id":"cf1508af905b3ba3d2e55d01551e312d235107ce"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"65f460a4d945dd68fa25e6e1789f71279207e2bd","unresolved":true,"context_lines":[{"line_number":561,"context_line":"        \"\"\""},{"line_number":562,"context_line":"        Returns a list of paths to async pending files found on given nodes."},{"line_number":563,"context_line":""},{"line_number":564,"context_line":"        :param onodes: a list of nodes. If None, check all object nodes."},{"line_number":565,"context_line":"        :return: a list of file paths."},{"line_number":566,"context_line":"        \"\"\""},{"line_number":567,"context_line":"        async_pendings \u003d []"}],"source_content_type":"text/x-python","patch_set":10,"id":"b6ab9cd3_d76f015c","line":564,"range":{"start_line":564,"start_character":49,"end_line":564,"end_character":71},"updated":"2024-02-02 23:02:49.000000000","message":"Seems like we **always** want this behavior.","commit_id":"cf1508af905b3ba3d2e55d01551e312d235107ce"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3cd765529239dc0f251989ddedd9b1443dccf0c7","unresolved":true,"context_lines":[{"line_number":561,"context_line":"        \"\"\""},{"line_number":562,"context_line":"        Returns a list of paths to async pending files found on given nodes."},{"line_number":563,"context_line":""},{"line_number":564,"context_line":"        :param onodes: a list of nodes. If None, check all object nodes."},{"line_number":565,"context_line":"        :return: a list of file paths."},{"line_number":566,"context_line":"        \"\"\""},{"line_number":567,"context_line":"        async_pendings \u003d []"}],"source_content_type":"text/x-python","patch_set":10,"id":"d7344ed1_798662ab","line":564,"range":{"start_line":564,"start_character":49,"end_line":564,"end_character":71},"in_reply_to":"b6ab9cd3_d76f015c","updated":"2024-02-05 05:27:42.000000000","message":"Yeah maybe. But it does make the helper method more useful if you know and only want to check a particular node.","commit_id":"cf1508af905b3ba3d2e55d01551e312d235107ce"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"081644230370a835def65f9537d1943cf77a40ed","unresolved":false,"context_lines":[{"line_number":561,"context_line":"        \"\"\""},{"line_number":562,"context_line":"        Returns a list of paths to async pending files found on given nodes."},{"line_number":563,"context_line":""},{"line_number":564,"context_line":"        :param onodes: a list of nodes. If None, check all object nodes."},{"line_number":565,"context_line":"        :return: a list of file paths."},{"line_number":566,"context_line":"        \"\"\""},{"line_number":567,"context_line":"        async_pendings \u003d []"}],"source_content_type":"text/x-python","patch_set":10,"id":"a7b4f6ce_6d8f6568","line":564,"range":{"start_line":564,"start_character":49,"end_line":564,"end_character":71},"in_reply_to":"d7344ed1_798662ab","updated":"2024-06-21 22:35:11.000000000","message":"Acknowledged","commit_id":"cf1508af905b3ba3d2e55d01551e312d235107ce"}],"test/probe/test_object_expirer.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"65f460a4d945dd68fa25e6e1789f71279207e2bd","unresolved":true,"context_lines":[{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        # expire the objects"},{"line_number":172,"context_line":"        Manager([\u0027object-expirer\u0027]).once()"},{"line_number":173,"context_line":"        pendings_after \u003d self.gather_async_pendings(all_obj_nodes)"},{"line_number":174,"context_line":"        self.assertEqual(pendings_after, pendings_before)"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def test_expirer_object_should_not_be_expired(self):"}],"source_content_type":"text/x-python","patch_set":10,"id":"bf600e48_dde87f16","side":"PARENT","line":173,"range":{"start_line":173,"start_character":52,"end_line":173,"end_character":65},"updated":"2024-02-02 23:02:49.000000000","message":"On py3, this was already exhausted! We\u0027ve been testing that\n```\npendings_before \u003d\u003d {} \u003d\u003d pendings_after\n```\n... which *does* jive with the comment\n```\n# Make sure there\u0027s no async_pendings anywhere.\n```\nbut it makes me wonder what the heck this before/after thing was all about...","commit_id":"5c659b1a6d31d47faaff1cc0066c732877e04838"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"081644230370a835def65f9537d1943cf77a40ed","unresolved":false,"context_lines":[{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        # expire the objects"},{"line_number":172,"context_line":"        Manager([\u0027object-expirer\u0027]).once()"},{"line_number":173,"context_line":"        pendings_after \u003d self.gather_async_pendings(all_obj_nodes)"},{"line_number":174,"context_line":"        self.assertEqual(pendings_after, pendings_before)"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def test_expirer_object_should_not_be_expired(self):"}],"source_content_type":"text/x-python","patch_set":10,"id":"a1a6c10f_bc180e4f","side":"PARENT","line":173,"range":{"start_line":173,"start_character":52,"end_line":173,"end_character":65},"in_reply_to":"26442aaa_782b234d","updated":"2024-06-21 22:35:11.000000000","message":"Acknowledged","commit_id":"5c659b1a6d31d47faaff1cc0066c732877e04838"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"3cd765529239dc0f251989ddedd9b1443dccf0c7","unresolved":true,"context_lines":[{"line_number":170,"context_line":""},{"line_number":171,"context_line":"        # expire the objects"},{"line_number":172,"context_line":"        Manager([\u0027object-expirer\u0027]).once()"},{"line_number":173,"context_line":"        pendings_after \u003d self.gather_async_pendings(all_obj_nodes)"},{"line_number":174,"context_line":"        self.assertEqual(pendings_after, pendings_before)"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def test_expirer_object_should_not_be_expired(self):"}],"source_content_type":"text/x-python","patch_set":10,"id":"26442aaa_782b234d","side":"PARENT","line":173,"range":{"start_line":173,"start_character":52,"end_line":173,"end_character":65},"in_reply_to":"bf600e48_dde87f16","updated":"2024-02-05 05:27:42.000000000","message":"I guess confirming the expirer didn\u0027t write any async pendings.. but yeah could slo just do an assertFalse check. But meh","commit_id":"5c659b1a6d31d47faaff1cc0066c732877e04838"}],"test/probe/test_sharder.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ce0edd2d95d5633444414ec60233a1a27a0bf0e5","unresolved":true,"context_lines":[{"line_number":1629,"context_line":"        self.put_objects(more_obj_names)"},{"line_number":1630,"context_line":"        self.brain.servers.start()"},{"line_number":1631,"context_line":""},{"line_number":1632,"context_line":"        async_files \u003d self.get_async_files()"},{"line_number":1633,"context_line":"        for af in async_files:"},{"line_number":1634,"context_line":"            # They should have a sharded db_state"},{"line_number":1635,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027sharded\u0027})"}],"source_content_type":"text/x-python","patch_set":6,"id":"1708c950_33da5e00","line":1632,"updated":"2023-05-25 04:44:05.000000000","message":"add \"self.assertTrue(async_files)\" after this line?","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"648c58b851d2681ab5b7ba381a171e354f2fc3dd","unresolved":false,"context_lines":[{"line_number":1629,"context_line":"        self.put_objects(more_obj_names)"},{"line_number":1630,"context_line":"        self.brain.servers.start()"},{"line_number":1631,"context_line":""},{"line_number":1632,"context_line":"        async_files \u003d self.get_async_files()"},{"line_number":1633,"context_line":"        for af in async_files:"},{"line_number":1634,"context_line":"            # They should have a sharded db_state"},{"line_number":1635,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027sharded\u0027})"}],"source_content_type":"text/x-python","patch_set":6,"id":"12186789_bf64b4ee","line":1632,"in_reply_to":"1708c950_33da5e00","updated":"2024-02-02 00:30:56.000000000","message":"Done","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d8c270170dc506fc0b80dd8b449be8f8c1f81df2","unresolved":false,"context_lines":[{"line_number":1629,"context_line":"        self.put_objects(more_obj_names)"},{"line_number":1630,"context_line":"        self.brain.servers.start()"},{"line_number":1631,"context_line":""},{"line_number":1632,"context_line":"        async_files \u003d self.get_async_files()"},{"line_number":1633,"context_line":"        for af in async_files:"},{"line_number":1634,"context_line":"            # They should have a sharded db_state"},{"line_number":1635,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027sharded\u0027})"}],"source_content_type":"text/x-python","patch_set":6,"id":"2ca207fa_f9c50c5a","line":1632,"in_reply_to":"1708c950_33da5e00","updated":"2024-02-02 00:42:07.000000000","message":"Done","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ce0edd2d95d5633444414ec60233a1a27a0bf0e5","unresolved":true,"context_lines":[{"line_number":1666,"context_line":"        self.put_objects(even_more_obj_names)"},{"line_number":1667,"context_line":"        self.brain.start_primary_half()"},{"line_number":1668,"context_line":""},{"line_number":1669,"context_line":"        async_files \u003d self.get_async_files()"},{"line_number":1670,"context_line":"        for af in async_files:"},{"line_number":1671,"context_line":"            # They should have a sharded db_state AND container_path"},{"line_number":1672,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027sharded\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"f759ada9_c1862ac1","line":1669,"updated":"2023-05-25 04:44:05.000000000","message":"add \"self.assertTrue(async_files)\" after this line?","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"648c58b851d2681ab5b7ba381a171e354f2fc3dd","unresolved":false,"context_lines":[{"line_number":1666,"context_line":"        self.put_objects(even_more_obj_names)"},{"line_number":1667,"context_line":"        self.brain.start_primary_half()"},{"line_number":1668,"context_line":""},{"line_number":1669,"context_line":"        async_files \u003d self.get_async_files()"},{"line_number":1670,"context_line":"        for af in async_files:"},{"line_number":1671,"context_line":"            # They should have a sharded db_state AND container_path"},{"line_number":1672,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027sharded\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"193bb89d_082b7868","line":1669,"in_reply_to":"f759ada9_c1862ac1","updated":"2024-02-02 00:30:56.000000000","message":"Done","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d8c270170dc506fc0b80dd8b449be8f8c1f81df2","unresolved":false,"context_lines":[{"line_number":1666,"context_line":"        self.put_objects(even_more_obj_names)"},{"line_number":1667,"context_line":"        self.brain.start_primary_half()"},{"line_number":1668,"context_line":""},{"line_number":1669,"context_line":"        async_files \u003d self.get_async_files()"},{"line_number":1670,"context_line":"        for af in async_files:"},{"line_number":1671,"context_line":"            # They should have a sharded db_state AND container_path"},{"line_number":1672,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027sharded\u0027,"}],"source_content_type":"text/x-python","patch_set":6,"id":"a8bc89c3_706881d0","line":1669,"in_reply_to":"f759ada9_c1862ac1","updated":"2024-02-02 00:42:07.000000000","message":"Done","commit_id":"1921f20f67401b06ef79e5e88186942aee329cb7"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"00847b561410942b182c38df4d3cdee556b12042","unresolved":true,"context_lines":[{"line_number":1465,"context_line":"            self.brain.servers.start(number\u003dn)"},{"line_number":1466,"context_line":""},{"line_number":1467,"context_line":"        # Check the async pendings, they are unsharded so that\u0027s the db_state"},{"line_number":1468,"context_line":"        async_files \u003d self.get_async_files()"},{"line_number":1469,"context_line":"        for af in async_files:"},{"line_number":1470,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027unsharded\u0027})"},{"line_number":1471,"context_line":"            self.assertNotInAsyncFile(af, [\u0027container_path\u0027])"}],"source_content_type":"text/x-python","patch_set":7,"id":"bc055718_44186245","line":1468,"updated":"2024-01-24 19:01:58.000000000","message":"Could also benefit from a `self.assertTrue(async_files)`","commit_id":"c898adde9495e5e390c70d60ac78bc5c122748e1"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"64e57382a13a66c2651148fffce6f3ca4a9ce130","unresolved":false,"context_lines":[{"line_number":1465,"context_line":"            self.brain.servers.start(number\u003dn)"},{"line_number":1466,"context_line":""},{"line_number":1467,"context_line":"        # Check the async pendings, they are unsharded so that\u0027s the db_state"},{"line_number":1468,"context_line":"        async_files \u003d self.get_async_files()"},{"line_number":1469,"context_line":"        for af in async_files:"},{"line_number":1470,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027unsharded\u0027})"},{"line_number":1471,"context_line":"            self.assertNotInAsyncFile(af, [\u0027container_path\u0027])"}],"source_content_type":"text/x-python","patch_set":7,"id":"68ff9e12_55f8f5ae","line":1468,"in_reply_to":"bc055718_44186245","updated":"2024-02-02 00:06:16.000000000","message":"Done","commit_id":"c898adde9495e5e390c70d60ac78bc5c122748e1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f85a311d98cb5c15af697f57481f31011341be8b","unresolved":true,"context_lines":[{"line_number":1477,"context_line":"    def get_async_files(self):"},{"line_number":1478,"context_line":"        # The async dir lives outside the datadir, so we just need the"},{"line_number":1479,"context_line":"        # devices dir to final all async pendings"},{"line_number":1480,"context_line":"        conf \u003d utils.readconf(self.configs[\u0027object-server\u0027][1],"},{"line_number":1481,"context_line":"                              section_name\u003d\u0027app:object-server\u0027)"},{"line_number":1482,"context_line":"        devices \u003d conf[\u0027devices\u0027]"},{"line_number":1483,"context_line":"        async_paths \u003d set()"}],"source_content_type":"text/x-python","patch_set":9,"id":"70e3eaa1_d020f819","line":1480,"updated":"2024-02-02 22:52:21.000000000","message":"Oh... and this is only valid for the first (or is it second?) server...\n\nCome to think of it, can we just use [`gather_async_pendings`](https://github.com/openstack/swift/blob/2.32.0/test/probe/common.py#L560)?","commit_id":"5ea38013b9586c1bcb97e380ff747d67e9516a38"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"65f460a4d945dd68fa25e6e1789f71279207e2bd","unresolved":false,"context_lines":[{"line_number":1477,"context_line":"    def get_async_files(self):"},{"line_number":1478,"context_line":"        # The async dir lives outside the datadir, so we just need the"},{"line_number":1479,"context_line":"        # devices dir to final all async pendings"},{"line_number":1480,"context_line":"        conf \u003d utils.readconf(self.configs[\u0027object-server\u0027][1],"},{"line_number":1481,"context_line":"                              section_name\u003d\u0027app:object-server\u0027)"},{"line_number":1482,"context_line":"        devices \u003d conf[\u0027devices\u0027]"},{"line_number":1483,"context_line":"        async_paths \u003d set()"}],"source_content_type":"text/x-python","patch_set":9,"id":"341fa492_71617d70","line":1480,"in_reply_to":"70e3eaa1_d020f819","updated":"2024-02-02 23:02:49.000000000","message":"Done","commit_id":"5ea38013b9586c1bcb97e380ff747d67e9516a38"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"f85a311d98cb5c15af697f57481f31011341be8b","unresolved":true,"context_lines":[{"line_number":1482,"context_line":"        devices \u003d conf[\u0027devices\u0027]"},{"line_number":1483,"context_line":"        async_paths \u003d set()"},{"line_number":1484,"context_line":""},{"line_number":1485,"context_line":"        for node in self.brain.nodes:"},{"line_number":1486,"context_line":"            async_dir \u003d os.path.join(devices, node[\u0027device\u0027], \u0027async_pending\u0027)"},{"line_number":1487,"context_line":"            if os.path.exists(async_dir):"},{"line_number":1488,"context_line":"                for suffix in os.listdir(async_dir):"}],"source_content_type":"text/x-python","patch_set":9,"id":"f1c88e36_49cf7e56","line":1485,"updated":"2024-02-02 22:52:21.000000000","message":"Wait, is our brain for object or container nodes?","commit_id":"5ea38013b9586c1bcb97e380ff747d67e9516a38"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"65f460a4d945dd68fa25e6e1789f71279207e2bd","unresolved":false,"context_lines":[{"line_number":1482,"context_line":"        devices \u003d conf[\u0027devices\u0027]"},{"line_number":1483,"context_line":"        async_paths \u003d set()"},{"line_number":1484,"context_line":""},{"line_number":1485,"context_line":"        for node in self.brain.nodes:"},{"line_number":1486,"context_line":"            async_dir \u003d os.path.join(devices, node[\u0027device\u0027], \u0027async_pending\u0027)"},{"line_number":1487,"context_line":"            if os.path.exists(async_dir):"},{"line_number":1488,"context_line":"                for suffix in os.listdir(async_dir):"}],"source_content_type":"text/x-python","patch_set":9,"id":"11ab42b8_224a3203","line":1485,"in_reply_to":"f1c88e36_49cf7e56","updated":"2024-02-02 23:02:49.000000000","message":"Done","commit_id":"5ea38013b9586c1bcb97e380ff747d67e9516a38"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"503f6ec205fcd5d435a64065737583430f602129","unresolved":true,"context_lines":[{"line_number":1483,"context_line":"        async_paths \u003d set()"},{"line_number":1484,"context_line":""},{"line_number":1485,"context_line":"        for node in self.brain.nodes:"},{"line_number":1486,"context_line":"            async_dir \u003d os.path.join(devices, node[\u0027device\u0027], \u0027async_pending\u0027)"},{"line_number":1487,"context_line":"            if os.path.exists(async_dir):"},{"line_number":1488,"context_line":"                for suffix in os.listdir(async_dir):"},{"line_number":1489,"context_line":"                    suffix_dir \u003d os.path.join(async_dir, suffix)"}],"source_content_type":"text/x-python","patch_set":9,"id":"6ac7d512_0d6286cf","line":1486,"range":{"start_line":1486,"start_character":63,"end_line":1486,"end_character":76},"updated":"2024-02-02 22:15:43.000000000","message":"Doesn\u0027t this depend on `self.brain.policy`?","commit_id":"5ea38013b9586c1bcb97e380ff747d67e9516a38"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"65f460a4d945dd68fa25e6e1789f71279207e2bd","unresolved":false,"context_lines":[{"line_number":1483,"context_line":"        async_paths \u003d set()"},{"line_number":1484,"context_line":""},{"line_number":1485,"context_line":"        for node in self.brain.nodes:"},{"line_number":1486,"context_line":"            async_dir \u003d os.path.join(devices, node[\u0027device\u0027], \u0027async_pending\u0027)"},{"line_number":1487,"context_line":"            if os.path.exists(async_dir):"},{"line_number":1488,"context_line":"                for suffix in os.listdir(async_dir):"},{"line_number":1489,"context_line":"                    suffix_dir \u003d os.path.join(async_dir, suffix)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5549d675_b7e9313c","line":1486,"range":{"start_line":1486,"start_character":63,"end_line":1486,"end_character":76},"in_reply_to":"6ac7d512_0d6286cf","updated":"2024-02-02 23:02:49.000000000","message":"Done","commit_id":"5ea38013b9586c1bcb97e380ff747d67e9516a38"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":1462,"context_line":"                continue"},{"line_number":1463,"context_line":""},{"line_number":1464,"context_line":"        if errors:"},{"line_number":1465,"context_line":"            self.fail(\u0027\\n\u0027.join(errors))"},{"line_number":1466,"context_line":""},{"line_number":1467,"context_line":"    def assertNotInAsyncFile(self, async_path, not_expect_keys):"},{"line_number":1468,"context_line":"        with open(async_path, \u0027rb\u0027) as fd:"}],"source_content_type":"text/x-python","patch_set":16,"id":"9fde4e0f_c19ec18b","line":1465,"updated":"2024-07-13 02:22:10.000000000","message":"with proxy changes reverted:\n\n```\nself \u003d \u003ctest.probe.test_sharder.TestContainerSharding testMethod\u003dtest_async_pendings\u003e\n\n    def test_async_pendings(self):\n        obj_names \u003d self._make_object_names(self.max_shard_size * 2)\n    \n        # There are some updates *everyone* gets\n        self.put_objects(obj_names[::5])\n        # But roll some outages so each container only get ~2/5 more object\n        # records i.e. total of 3/5 updates per container; and async pendings\n        # pile up\n        for i, n in enumerate(self.brain.node_numbers, start\u003d1):\n            self.brain.servers.stop(number\u003dn)\n            self.put_objects(obj_names[i::5])\n            self.brain.servers.start(number\u003dn)\n    \n        # Check the async pendings, they are unsharded so that\u0027s the db_state\n        async_files \u003d self.gather_async_pendings()\n        self.assertTrue(async_files)\n        for af in async_files:\n\u003e           self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027unsharded\u0027})\n\nswift/test/probe/test_sharder.py:1498: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nswift/test/probe/test_sharder.py:1465: in assertInAsyncFile\n    self.fail(\u0027\\n\u0027.join(errors))\nE   AssertionError: Exp value unsharded !\u003d None\n```\n\nWith object-server changes reverted:\n\n```\n_________________________________________________________________________ TestContainerSharding.test_async_pendings __________________________________________________________________________\n\nself \u003d \u003ctest.probe.test_sharder.TestContainerSharding testMethod\u003dtest_async_pendings\u003e\n\n    def test_async_pendings(self):\n        obj_names \u003d self._make_object_names(self.max_shard_size * 2)\n    \n        # There are some updates *everyone* gets\n        self.put_objects(obj_names[::5])\n        # But roll some outages so each container only get ~2/5 more object\n        # records i.e. total of 3/5 updates per container; and async pendings\n        # pile up\n        for i, n in enumerate(self.brain.node_numbers, start\u003d1):\n            self.brain.servers.stop(number\u003dn)\n            self.put_objects(obj_names[i::5])\n            self.brain.servers.start(number\u003dn)\n    \n        # Check the async pendings, they are unsharded so that\u0027s the db_state\n        async_files \u003d self.gather_async_pendings()\n        self.assertTrue(async_files)\n        for af in async_files:\n\u003e           self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027unsharded\u0027})\n\nswift/test/probe/test_sharder.py:1498: \n_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \nswift/test/probe/test_sharder.py:1465: in assertInAsyncFile\n    self.fail(\u0027\\n\u0027.join(errors))\nE   AssertionError: Key \u0027db_state\u0027 does not exist\n```","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":1696,"context_line":"        self.brain.start_primary_half()"},{"line_number":1697,"context_line":""},{"line_number":1698,"context_line":"        async_files \u003d self.gather_async_pendings()"},{"line_number":1699,"context_line":"        self.assertTrue(async_files)"},{"line_number":1700,"context_line":"        for af in async_files:"},{"line_number":1701,"context_line":"            # They should have a sharded db_state AND container_path"},{"line_number":1702,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027sharded\u0027,"}],"source_content_type":"text/x-python","patch_set":16,"id":"09bb46b1_85b4f684","line":1699,"updated":"2024-07-13 02:22:10.000000000","message":"this assertion is clutch!  KUDOS!","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":1700,"context_line":"        for af in async_files:"},{"line_number":1701,"context_line":"            # They should have a sharded db_state AND container_path"},{"line_number":1702,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027sharded\u0027,"},{"line_number":1703,"context_line":"                                        \u0027container_path\u0027: mock.ANY})"},{"line_number":1704,"context_line":""},{"line_number":1705,"context_line":"        Manager([\u0027object-updater\u0027]).once()"},{"line_number":1706,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"8983d838_11af502f","line":1703,"updated":"2024-07-13 02:22:10.000000000","message":"this feels pretty good - we\u0027re asserting not only that the db_state \u0027sharded\u0027 and \u0027unsharded\u0027 make it to the backend server correctly when the container_path is set and it\u0027s actually sharded or not... we\u0027re even making sure it will make it into the async pending on disk if the update fails.\n\nFWIW OMM this was consistently `expected_shard_ranges[-1].name` e.g.\n\n.shards_AUTH_test/container-f64325da-a7ae-4df7-b470-76d3041088a2-145180caa2c995f04bc9694bce94b18c-1720835304.05216-2","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b756ed925c28f037601609fd1c67a3f2a7676dca","unresolved":false,"context_lines":[{"line_number":1700,"context_line":"        for af in async_files:"},{"line_number":1701,"context_line":"            # They should have a sharded db_state AND container_path"},{"line_number":1702,"context_line":"            self.assertInAsyncFile(af, {\u0027db_state\u0027: \u0027sharded\u0027,"},{"line_number":1703,"context_line":"                                        \u0027container_path\u0027: mock.ANY})"},{"line_number":1704,"context_line":""},{"line_number":1705,"context_line":"        Manager([\u0027object-updater\u0027]).once()"},{"line_number":1706,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"d401c652_8a1da4fa","line":1703,"in_reply_to":"8983d838_11af502f","updated":"2024-07-15 13:07:51.000000000","message":"addressed in 924108: trivial: refactor _get_update_target | https://review.opendev.org/c/openstack/swift/+/924108","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"}],"test/unit/obj/test_server.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"6d842e9801adf006acfe05e0a6816b1a10799b18","unresolved":true,"context_lines":[{"line_number":1185,"context_line":"             \u0027account\u0027: \u0027a\u0027, \u0027container\u0027: \u0027c\u0027, \u0027obj\u0027: \u0027o\u0027, \u0027op\u0027: \u0027PUT\u0027,"},{"line_number":1186,"context_line":"             \u0027container_path\u0027: \u0027.sharded_a/c_shard_1\u0027,"},{"line_number":1187,"context_line":"             \u0027db_state\u0027: \u0027sharded\u0027 if container_path else \u0027unsharded\u0027},"},{"line_number":1188,"context_line":"            pickle.load(open(async_pending_file_put, \u0027rb\u0027)))"},{"line_number":1189,"context_line":""},{"line_number":1190,"context_line":"        # when updater is run its first request will be to the redirect"},{"line_number":1191,"context_line":"        # location that is persisted in the async pending file"}],"source_content_type":"text/x-python","patch_set":4,"id":"3deffb23_9ac8379d","line":1188,"updated":"2023-05-22 23:30:16.000000000","message":"is it easy to modify a current async update probe test and check if this pickle file has correct container state? not sure how to get the path of it in the probe tests.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"db63e260e775cf6ff00a6c7fb0b8e6d6d2f11a85","unresolved":true,"context_lines":[{"line_number":1185,"context_line":"             \u0027account\u0027: \u0027a\u0027, \u0027container\u0027: \u0027c\u0027, \u0027obj\u0027: \u0027o\u0027, \u0027op\u0027: \u0027PUT\u0027,"},{"line_number":1186,"context_line":"             \u0027container_path\u0027: \u0027.sharded_a/c_shard_1\u0027,"},{"line_number":1187,"context_line":"             \u0027db_state\u0027: \u0027sharded\u0027 if container_path else \u0027unsharded\u0027},"},{"line_number":1188,"context_line":"            pickle.load(open(async_pending_file_put, \u0027rb\u0027)))"},{"line_number":1189,"context_line":""},{"line_number":1190,"context_line":"        # when updater is run its first request will be to the redirect"},{"line_number":1191,"context_line":"        # location that is persisted in the async pending file"}],"source_content_type":"text/x-python","patch_set":4,"id":"61b45e86_4e8a79e3","line":1188,"in_reply_to":"3deffb23_9ac8379d","updated":"2023-05-23 04:06:34.000000000","message":"not a bad idea.. yeah should probably not only write unit tests.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"ce0edd2d95d5633444414ec60233a1a27a0bf0e5","unresolved":false,"context_lines":[{"line_number":1185,"context_line":"             \u0027account\u0027: \u0027a\u0027, \u0027container\u0027: \u0027c\u0027, \u0027obj\u0027: \u0027o\u0027, \u0027op\u0027: \u0027PUT\u0027,"},{"line_number":1186,"context_line":"             \u0027container_path\u0027: \u0027.sharded_a/c_shard_1\u0027,"},{"line_number":1187,"context_line":"             \u0027db_state\u0027: \u0027sharded\u0027 if container_path else \u0027unsharded\u0027},"},{"line_number":1188,"context_line":"            pickle.load(open(async_pending_file_put, \u0027rb\u0027)))"},{"line_number":1189,"context_line":""},{"line_number":1190,"context_line":"        # when updater is run its first request will be to the redirect"},{"line_number":1191,"context_line":"        # location that is persisted in the async pending file"}],"source_content_type":"text/x-python","patch_set":4,"id":"383d2791_c0554b46","line":1188,"in_reply_to":"61b45e86_4e8a79e3","updated":"2023-05-25 04:44:05.000000000","message":"Done","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"}],"test/unit/obj/test_updater.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":true,"context_lines":[{"line_number":753,"context_line":"            data[\u0027db_state\u0027] \u003d db_state"},{"line_number":754,"context_line":"        if container_path:"},{"line_number":755,"context_line":"            data[\u0027container_path\u0027] \u003d container_path"},{"line_number":756,"context_line":"            data[\u0027db_state\u0027] \u003d \u0027sharded\u0027"},{"line_number":757,"context_line":"        dfmanager.pickle_async_update(self.sda1, account, container, obj,"},{"line_number":758,"context_line":"                                      data, timestamp, policy)"},{"line_number":759,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"2379f399_2c1beeca","line":756,"updated":"2023-05-22 19:43:00.000000000","message":"oic, this is a Fake - we don\u0027t actually ever ignore the state sent by the proxy.. \n\n.. so it\u0027s sort of a BAD fake ...\n\nprobably better to have callers explicitly pass db_state sharded when the pass in container_path","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"db63e260e775cf6ff00a6c7fb0b8e6d6d2f11a85","unresolved":true,"context_lines":[{"line_number":753,"context_line":"            data[\u0027db_state\u0027] \u003d db_state"},{"line_number":754,"context_line":"        if container_path:"},{"line_number":755,"context_line":"            data[\u0027container_path\u0027] \u003d container_path"},{"line_number":756,"context_line":"            data[\u0027db_state\u0027] \u003d \u0027sharded\u0027"},{"line_number":757,"context_line":"        dfmanager.pickle_async_update(self.sda1, account, container, obj,"},{"line_number":758,"context_line":"                                      data, timestamp, policy)"},{"line_number":759,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"e0830989_242d3bd8","line":756,"in_reply_to":"2379f399_2c1beeca","updated":"2023-05-23 04:06:34.000000000","message":"yeah, not just a bad fake, but a lazy Matt, as it meant I didn\u0027t have to modify the callers so much :P","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"64e57382a13a66c2651148fffce6f3ca4a9ce130","unresolved":false,"context_lines":[{"line_number":753,"context_line":"            data[\u0027db_state\u0027] \u003d db_state"},{"line_number":754,"context_line":"        if container_path:"},{"line_number":755,"context_line":"            data[\u0027container_path\u0027] \u003d container_path"},{"line_number":756,"context_line":"            data[\u0027db_state\u0027] \u003d \u0027sharded\u0027"},{"line_number":757,"context_line":"        dfmanager.pickle_async_update(self.sda1, account, container, obj,"},{"line_number":758,"context_line":"                                      data, timestamp, policy)"},{"line_number":759,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"f01cb2e7_451ef071","line":756,"in_reply_to":"be776a86_20602baa","updated":"2024-02-02 00:06:16.000000000","message":"yeah, good point","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"00847b561410942b182c38df4d3cdee556b12042","unresolved":true,"context_lines":[{"line_number":753,"context_line":"            data[\u0027db_state\u0027] \u003d db_state"},{"line_number":754,"context_line":"        if container_path:"},{"line_number":755,"context_line":"            data[\u0027container_path\u0027] \u003d container_path"},{"line_number":756,"context_line":"            data[\u0027db_state\u0027] \u003d \u0027sharded\u0027"},{"line_number":757,"context_line":"        dfmanager.pickle_async_update(self.sda1, account, container, obj,"},{"line_number":758,"context_line":"                                      data, timestamp, policy)"},{"line_number":759,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"be776a86_20602baa","line":756,"in_reply_to":"e0830989_242d3bd8","updated":"2024-01-24 19:01:58.000000000","message":"I mean, do we actually *need* any of this yet? Seems like it belongs more with the patch that actually touches the updater...","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"}],"test/unit/proxy/test_server.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":true,"context_lines":[{"line_number":7135,"context_line":"        # an X-Backend-Quoted-Container-Path with a shard name."},{"line_number":7136,"context_line":"        for db_state, expect_cont_path in ("},{"line_number":7137,"context_line":"                (NOTFOUND, False), (UNSHARDED, False), (SHARDING, True),"},{"line_number":7138,"context_line":"                (SHARDED, True), (COLLAPSED, False)):"},{"line_number":7139,"context_line":"            crafted_container_info[\u0027sharding_state\u0027] \u003d db_state"},{"line_number":7140,"context_line":"            req \u003d Request.blank("},{"line_number":7141,"context_line":"                \u0027/v1/a/c/o\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"b168acf1_c134a17c","line":7138,"updated":"2023-05-22 19:43:00.000000000","message":"interesting, so there\u0027s a number of different state values we can expect to be stored in the container_info cache","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":7135,"context_line":"        # an X-Backend-Quoted-Container-Path with a shard name."},{"line_number":7136,"context_line":"        for db_state, expect_cont_path in ("},{"line_number":7137,"context_line":"                (NOTFOUND, False), (UNSHARDED, False), (SHARDING, True),"},{"line_number":7138,"context_line":"                (SHARDED, True), (COLLAPSED, False)):"},{"line_number":7139,"context_line":"            crafted_container_info[\u0027sharding_state\u0027] \u003d db_state"},{"line_number":7140,"context_line":"            req \u003d Request.blank("},{"line_number":7141,"context_line":"                \u0027/v1/a/c/o\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"fdae09ca_4886202d","line":7138,"in_reply_to":"47d14148_cd6de527","updated":"2024-07-13 02:22:10.000000000","message":"I was probably just expecting to see more than one test case.  here\u0027s what happens when you read a cache object from old swift, here\u0027s what happens when hit an unsharded container, here\u0027s what happens when you hit sharded container, here\u0027s what happens when you hit a sharding container (note it\u0027s the same as sharded because we redirect new updates before we redirect listings!)\n\nbut ultimately I guess it\u0027s all the same - if `container_info[\u0027sharding_state\u0027]` was \"booberries\" - that\u0027s what we\u0027d send to the object servers!  And I think this test sort of demonstrates that well enough.\n\nthe `expect_cont_path` which triggers a conditional assertion is particularlly interesting!  It\u0027s a little unrealistic/misleading in that the conditional doesn\u0027t effect the captured host/part - just whether we look for the X-Backend-Quoted-Container-Path... which we *don\u0027t* assert is *missing*","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"db63e260e775cf6ff00a6c7fb0b8e6d6d2f11a85","unresolved":true,"context_lines":[{"line_number":7135,"context_line":"        # an X-Backend-Quoted-Container-Path with a shard name."},{"line_number":7136,"context_line":"        for db_state, expect_cont_path in ("},{"line_number":7137,"context_line":"                (NOTFOUND, False), (UNSHARDED, False), (SHARDING, True),"},{"line_number":7138,"context_line":"                (SHARDED, True), (COLLAPSED, False)):"},{"line_number":7139,"context_line":"            crafted_container_info[\u0027sharding_state\u0027] \u003d db_state"},{"line_number":7140,"context_line":"            req \u003d Request.blank("},{"line_number":7141,"context_line":"                \u0027/v1/a/c/o\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"47d14148_cd6de527","line":7138,"in_reply_to":"b168acf1_c134a17c","updated":"2023-05-23 04:06:34.000000000","message":"yes and no, I figured if we\u0027re going to pass the db_state down might as well test them all. I don\u0027t think we\u0027d ever really pass the NOTFOUND for example as if the db file didnt exist we wouldn\u0027t get a success and so no info would be written to cachce. But by putting the db_state into info_cache I can test the container headers generation code and simulate getting an info with said states.\n\nI can remove all but the ones except those I\u0027d expect if you want?","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b756ed925c28f037601609fd1c67a3f2a7676dca","unresolved":false,"context_lines":[{"line_number":7135,"context_line":"        # an X-Backend-Quoted-Container-Path with a shard name."},{"line_number":7136,"context_line":"        for db_state, expect_cont_path in ("},{"line_number":7137,"context_line":"                (NOTFOUND, False), (UNSHARDED, False), (SHARDING, True),"},{"line_number":7138,"context_line":"                (SHARDED, True), (COLLAPSED, False)):"},{"line_number":7139,"context_line":"            crafted_container_info[\u0027sharding_state\u0027] \u003d db_state"},{"line_number":7140,"context_line":"            req \u003d Request.blank("},{"line_number":7141,"context_line":"                \u0027/v1/a/c/o\u0027,"}],"source_content_type":"text/x-python","patch_set":4,"id":"8fe021bc_e7bbc663","line":7138,"in_reply_to":"fdae09ca_4886202d","updated":"2024-07-15 13:07:51.000000000","message":"addressed in 924108: trivial: refactor _get_update_target | https://review.opendev.org/c/openstack/swift/+/924108","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b760137b248932b0d0327c46cd24cb565a3798b1","unresolved":true,"context_lines":[{"line_number":7336,"context_line":"            {\u0027X-Container-Host\u0027: \u002710.0.0.2:1002\u0027,"},{"line_number":7337,"context_line":"             \u0027X-Container-Partition\u0027: \u00270\u0027,"},{"line_number":7338,"context_line":"             \u0027X-Container-Device\u0027: \u0027sdc\u0027,"},{"line_number":7339,"context_line":"             \u0027X-Container-Db-State\u0027: \u0027unsharded\u0027}"},{"line_number":7340,"context_line":"        ])"},{"line_number":7341,"context_line":""},{"line_number":7342,"context_line":"    @mock.patch(\u0027time.time\u0027, new\u003dlambda: STATIC_TIME)"}],"source_content_type":"text/x-python","patch_set":4,"id":"3b53c849_9fa686b1","line":7339,"updated":"2023-05-22 19:43:00.000000000","message":"but mostly I\u0027m seeing existing tests updated with the unsharded state - I guess whatever is in cache gets passed down the async update transparently, maybe the specific db_state value just doesn\u0027t matter WRT to behavior","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"db63e260e775cf6ff00a6c7fb0b8e6d6d2f11a85","unresolved":true,"context_lines":[{"line_number":7336,"context_line":"            {\u0027X-Container-Host\u0027: \u002710.0.0.2:1002\u0027,"},{"line_number":7337,"context_line":"             \u0027X-Container-Partition\u0027: \u00270\u0027,"},{"line_number":7338,"context_line":"             \u0027X-Container-Device\u0027: \u0027sdc\u0027,"},{"line_number":7339,"context_line":"             \u0027X-Container-Db-State\u0027: \u0027unsharded\u0027}"},{"line_number":7340,"context_line":"        ])"},{"line_number":7341,"context_line":""},{"line_number":7342,"context_line":"    @mock.patch(\u0027time.time\u0027, new\u003dlambda: STATIC_TIME)"}],"source_content_type":"text/x-python","patch_set":4,"id":"81fa206e_9a1e2333","line":7339,"in_reply_to":"3b53c849_9fa686b1","updated":"2023-05-23 04:06:34.000000000","message":"yeah, also because the mocked 200 HEAD responses we use in most tests is returning a defaulted info that uses unsharded db_state by default.\n\nI guess I could return valid response headers for the HEADs in all the tests, but thats also why I did the info trick in test_x_container_headers_db_state so I could confirm other options.","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":7336,"context_line":"            {\u0027X-Container-Host\u0027: \u002710.0.0.2:1002\u0027,"},{"line_number":7337,"context_line":"             \u0027X-Container-Partition\u0027: \u00270\u0027,"},{"line_number":7338,"context_line":"             \u0027X-Container-Device\u0027: \u0027sdc\u0027,"},{"line_number":7339,"context_line":"             \u0027X-Container-Db-State\u0027: \u0027unsharded\u0027}"},{"line_number":7340,"context_line":"        ])"},{"line_number":7341,"context_line":""},{"line_number":7342,"context_line":"    @mock.patch(\u0027time.time\u0027, new\u003dlambda: STATIC_TIME)"}],"source_content_type":"text/x-python","patch_set":4,"id":"d3b950b0_4474bdb2","line":7339,"in_reply_to":"81fa206e_9a1e2333","updated":"2024-07-13 02:22:10.000000000","message":"Acknowledged","commit_id":"ac80aa9e348ccbb28b0168f05710b3a95bc4fbb6"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a28b57a57503e583a2415e26bbb3e1e164c69ec5","unresolved":true,"context_lines":[{"line_number":2544,"context_line":"            self.assertEqual(gotten_obj, obj)"},{"line_number":2545,"context_line":""},{"line_number":2546,"context_line":"            sleep(0.3)  # client_timeout should kick us off"},{"line_number":2547,"context_line":"            sock.close()  # explicitly close the socket"},{"line_number":2548,"context_line":""},{"line_number":2549,"context_line":"            fd.write((\u0027GET /v1/a/%s/go-get-it HTTP/1.1\\r\\n\u0027"},{"line_number":2550,"context_line":"                      \u0027Host: localhost\\r\\n\u0027"}],"source_content_type":"text/x-python","patch_set":14,"id":"b415ca46_0de3f5ee","line":2547,"updated":"2024-05-03 21:18:27.000000000","message":"Why\u0027d we add this?","commit_id":"eaed0d3e73a0ad0a5ee5e3299c2448c332fb3d66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"081644230370a835def65f9537d1943cf77a40ed","unresolved":false,"context_lines":[{"line_number":2544,"context_line":"            self.assertEqual(gotten_obj, obj)"},{"line_number":2545,"context_line":""},{"line_number":2546,"context_line":"            sleep(0.3)  # client_timeout should kick us off"},{"line_number":2547,"context_line":"            sock.close()  # explicitly close the socket"},{"line_number":2548,"context_line":""},{"line_number":2549,"context_line":"            fd.write((\u0027GET /v1/a/%s/go-get-it HTTP/1.1\\r\\n\u0027"},{"line_number":2550,"context_line":"                      \u0027Host: localhost\\r\\n\u0027"}],"source_content_type":"text/x-python","patch_set":14,"id":"f1a261d8_72a4b995","line":2547,"in_reply_to":"35b6bcbe_394d0bd4","updated":"2024-06-21 22:35:11.000000000","message":"Done","commit_id":"eaed0d3e73a0ad0a5ee5e3299c2448c332fb3d66"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"0eda96e9d894a14ef1d6386778be482c715026d6","unresolved":true,"context_lines":[{"line_number":2544,"context_line":"            self.assertEqual(gotten_obj, obj)"},{"line_number":2545,"context_line":""},{"line_number":2546,"context_line":"            sleep(0.3)  # client_timeout should kick us off"},{"line_number":2547,"context_line":"            sock.close()  # explicitly close the socket"},{"line_number":2548,"context_line":""},{"line_number":2549,"context_line":"            fd.write((\u0027GET /v1/a/%s/go-get-it HTTP/1.1\\r\\n\u0027"},{"line_number":2550,"context_line":"                      \u0027Host: localhost\\r\\n\u0027"}],"source_content_type":"text/x-python","patch_set":14,"id":"35b6bcbe_394d0bd4","line":2547,"in_reply_to":"b415ca46_0de3f5ee","updated":"2024-05-15 06:06:08.000000000","message":"not that I can\u0027t remember.. I assume I did so for a reason, or it\u0027s something last lasted from rebases of ages past :P\n\n[Update] - nope it was me. I\u0027ll remove it and find out why\n[Update2] - Remove it and it seemd so work.. so :shrug:\n            Will push up a new version soon.","commit_id":"eaed0d3e73a0ad0a5ee5e3299c2448c332fb3d66"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"a28b57a57503e583a2415e26bbb3e1e164c69ec5","unresolved":true,"context_lines":[{"line_number":2554,"context_line":"            # makefile is a little weird, but this is disconnected"},{"line_number":2555,"context_line":"            self.assertEqual(b\u0027\u0027, fd.read())"},{"line_number":2556,"context_line":"            # I expected this to raise a socket error"},{"line_number":2557,"context_line":"            self.assertEqual(b\u0027\u0027, sock.recv(1024))"},{"line_number":2558,"context_line":"            # ... but we ARE disconnected"},{"line_number":2559,"context_line":"            with self.assertRaises(socket.error) as caught:"},{"line_number":2560,"context_line":"                sock.send(b\u0027test\u0027)"}],"source_content_type":"text/x-python","patch_set":14,"id":"dfb6f078_69c0c750","line":2557,"updated":"2024-05-03 21:18:27.000000000","message":"Looks like on py2, the `close()` causes this to start raising `EBADF`...","commit_id":"eaed0d3e73a0ad0a5ee5e3299c2448c332fb3d66"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":2554,"context_line":"            # makefile is a little weird, but this is disconnected"},{"line_number":2555,"context_line":"            self.assertEqual(b\u0027\u0027, fd.read())"},{"line_number":2556,"context_line":"            # I expected this to raise a socket error"},{"line_number":2557,"context_line":"            self.assertEqual(b\u0027\u0027, sock.recv(1024))"},{"line_number":2558,"context_line":"            # ... but we ARE disconnected"},{"line_number":2559,"context_line":"            with self.assertRaises(socket.error) as caught:"},{"line_number":2560,"context_line":"                sock.send(b\u0027test\u0027)"}],"source_content_type":"text/x-python","patch_set":14,"id":"f8d004f7_211f6cc2","line":2557,"in_reply_to":"dfb6f078_69c0c750","updated":"2024-07-13 02:22:10.000000000","message":"I think this comment is unrelated - maybe addressed in another patch?","commit_id":"eaed0d3e73a0ad0a5ee5e3299c2448c332fb3d66"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":2571,"context_line":"    \"\"\""},{"line_number":2572,"context_line":"    Test suite for replication policy"},{"line_number":2573,"context_line":"    \"\"\""},{"line_number":2574,"context_line":""},{"line_number":2575,"context_line":"    def setUp(self):"},{"line_number":2576,"context_line":"        skip_if_no_xattrs()"},{"line_number":2577,"context_line":"        _test_servers[0].error_limiter.stats.clear()  # clear out errors"}],"source_content_type":"text/x-python","patch_set":16,"id":"04c51955_a3931f3c","line":2574,"updated":"2024-07-13 02:22:10.000000000","message":"normally unrelated whitespace in diffs annoys me but I actually prefer the separation of doc-string and first method so I think it\u0027s fine ;)","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":7340,"context_line":"            captured \u003d {}"},{"line_number":7341,"context_line":"            for header in header_list:"},{"line_number":7342,"context_line":"                captured[header] \u003d headers.get(header)"},{"line_number":7343,"context_line":"            seen_headers.append(captured)"},{"line_number":7344,"context_line":""},{"line_number":7345,"context_line":"        with save_globals():"},{"line_number":7346,"context_line":"            self.app.allow_account_management \u003d True"}],"source_content_type":"text/x-python","patch_set":16,"id":"fbaf096e_c5755157","line":7343,"updated":"2024-07-13 02:22:10.000000000","message":"since NO ONE wants headers from the account/container HEAD requests (if they even exist) probably better just have this method only collect object server request headers.","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b756ed925c28f037601609fd1c67a3f2a7676dca","unresolved":false,"context_lines":[{"line_number":7340,"context_line":"            captured \u003d {}"},{"line_number":7341,"context_line":"            for header in header_list:"},{"line_number":7342,"context_line":"                captured[header] \u003d headers.get(header)"},{"line_number":7343,"context_line":"            seen_headers.append(captured)"},{"line_number":7344,"context_line":""},{"line_number":7345,"context_line":"        with save_globals():"},{"line_number":7346,"context_line":"            self.app.allow_account_management \u003d True"}],"source_content_type":"text/x-python","patch_set":16,"id":"42aff610_a66ed2da","line":7343,"in_reply_to":"fbaf096e_c5755157","updated":"2024-07-15 13:07:51.000000000","message":"addressed in 924108: trivial: refactor _get_update_target | https://review.opendev.org/c/openstack/swift/+/924108","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":7372,"context_line":"            \u0027created_at\u0027: \u00271\u0027, \u0027put_timestamp\u0027: None,"},{"line_number":7373,"context_line":"            \u0027delete_timestamp\u0027: None,"},{"line_number":7374,"context_line":"            \u0027status_changed_at\u0027: None"},{"line_number":7375,"context_line":"        }"},{"line_number":7376,"context_line":"        shardrange \u003d ShardRange(\u0027.sharded_a/c_something\u0027, 0, \u0027m\u0027, \u0027z\u0027)"},{"line_number":7377,"context_line":""},{"line_number":7378,"context_line":"        # We should always get X-Container-Root-Db-State with the current"}],"source_content_type":"text/x-python","patch_set":16,"id":"8d61cd88_11339068","line":7375,"updated":"2024-07-13 02:22:10.000000000","message":"so this is stubbed into the request environ swift.infocache below and pulled out in `BaseController.container_info` where the return `container_info` dict is annotated with partition and node","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":false,"context_lines":[{"line_number":7373,"context_line":"            \u0027delete_timestamp\u0027: None,"},{"line_number":7374,"context_line":"            \u0027status_changed_at\u0027: None"},{"line_number":7375,"context_line":"        }"},{"line_number":7376,"context_line":"        shardrange \u003d ShardRange(\u0027.sharded_a/c_something\u0027, 0, \u0027m\u0027, \u0027z\u0027)"},{"line_number":7377,"context_line":""},{"line_number":7378,"context_line":"        # We should always get X-Container-Root-Db-State with the current"},{"line_number":7379,"context_line":"        # db_state and when db_state is either sharding or sharded we should"}],"source_content_type":"text/x-python","patch_set":16,"id":"b7c62d3c_b2859faa","line":7376,"updated":"2024-07-13 02:22:10.000000000","message":"why does *this* path have the same partition and node as `a/c`!?\n\noh... because of FakeRing\n\n```\n\u003e /home/vagrant/swift/swift/proxy/controllers/obj.py(410)_get_update_target()\n-\u003e partition, nodes \u003d self.app.container_ring.get_nodes(\n(Pdb) l\n405  \t                req, self.account_name, self.container_name, self.object_name)\n406  \t            if update_shard_ns:\n407  \t                override_target_name \u003d update_shard_ns.name\n408  \t                import pdb\n409  \t                pdb.set_trace()\n410  -\u003e\t                partition, nodes \u003d self.app.container_ring.get_nodes(\n411  \t                    update_shard_ns.account, update_shard_ns.container)\n412  \t        else:\n413  \t            # for unsharded updates, a falsey value for target_name will\n414  \t            # prevent caller from adding X-Backend-Quoted-Container-Path\n415  \t            override_target_name \u003d None\n(Pdb) container_info[\u0027partition\u0027]\n0\n(Pdb) container_info[\u0027nodes\u0027]\n[{\u0027ip\u0027: \u002710.0.0.0\u0027, \u0027replication_ip\u0027: \u002710.0.0.0\u0027, \u0027port\u0027: 1000, \u0027replication_port\u0027: 1000, \u0027device\u0027: \u0027sda\u0027, \u0027zone\u0027: 0, \u0027region\u0027: 0, \u0027id\u0027: 0, \u0027weight\u0027: 1, \u0027index\u0027: 0}, {\u0027ip\u0027: \u002710.0.0.1\u0027, \u0027replication_ip\u0027: \u002710.0.0.1\u0027, \u0027port\u0027: 1001, \u0027replication_port\u0027: 1001, \u0027device\u0027: \u0027sdb\u0027, \u0027zone\u0027: 1, \u0027region\u0027: 1, \u0027id\u0027: 1, \u0027weight\u0027: 1, \u0027index\u0027: 1}, {\u0027ip\u0027: \u002710.0.0.2\u0027, \u0027replication_ip\u0027: \u002710.0.0.2\u0027, \u0027port\u0027: 1002, \u0027replication_port\u0027: 1002, \u0027device\u0027: \u0027sdc\u0027, \u0027zone\u0027: 2, \u0027region\u0027: 0, \u0027id\u0027: 2, \u0027weight\u0027: 1, \u0027index\u0027: 2}]\n(Pdb) container_info[\u0027nodes\u0027][0][\u0027device\u0027]\n\u0027sda\u0027\n(Pdb) part, nodes \u003d self.app.container_info.get_nodes(\u0027foo\u0027, \u0027bar\u0027)\n*** AttributeError: \u0027Application\u0027 object has no attribute \u0027container_info\u0027. Did you mean: \u0027container_ring\u0027?\n(Pdb) part, nodes \u003d self.app.container_ring.get_nodes(\u0027foo\u0027, \u0027bar\u0027)\n(Pdb) !part\n0\n(Pdb) nodes[0][\u0027device\u0027]\n\u0027sda\u0027\n(Pdb) \n```\n\nhttps://github.com/NVIDIA/swift/blob/master/test/unit/__init__.py#L226\n\nFINE.","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":7416,"context_line":"                controller \u003d ReplicatedObjectController("},{"line_number":7417,"context_line":"                    self.app, \u0027a\u0027, \u0027c\u0027, \u0027o\u0027)"},{"line_number":7418,"context_line":"                seen_headers \u003d self._gather_x_container_headers("},{"line_number":7419,"context_line":"                    controller.PUT, req,"},{"line_number":7420,"context_line":"                    201, 201, 201,  # PUT PUT PUT"},{"line_number":7421,"context_line":"                    header_list\u003dexp_seen_header_list, no_heads\u003dTrue)"},{"line_number":7422,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"c2d1ed15_286fce29","line":7419,"updated":"2024-07-13 02:22:10.000000000","message":"should we test controller.POST too?!\n\nOh MAN i can\u0027t *wait* for subTest!\n\nhttps://docs.python.org/3/library/unittest.html#unittest.TestCase.subTest","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b756ed925c28f037601609fd1c67a3f2a7676dca","unresolved":false,"context_lines":[{"line_number":7416,"context_line":"                controller \u003d ReplicatedObjectController("},{"line_number":7417,"context_line":"                    self.app, \u0027a\u0027, \u0027c\u0027, \u0027o\u0027)"},{"line_number":7418,"context_line":"                seen_headers \u003d self._gather_x_container_headers("},{"line_number":7419,"context_line":"                    controller.PUT, req,"},{"line_number":7420,"context_line":"                    201, 201, 201,  # PUT PUT PUT"},{"line_number":7421,"context_line":"                    header_list\u003dexp_seen_header_list, no_heads\u003dTrue)"},{"line_number":7422,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"124a7fb7_c9dbcfd0","line":7419,"in_reply_to":"c2d1ed15_286fce29","updated":"2024-07-15 13:07:51.000000000","message":"addressed in 924108: trivial: refactor _get_update_target | https://review.opendev.org/c/openstack/swift/+/924108","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":7418,"context_line":"                seen_headers \u003d self._gather_x_container_headers("},{"line_number":7419,"context_line":"                    controller.PUT, req,"},{"line_number":7420,"context_line":"                    201, 201, 201,  # PUT PUT PUT"},{"line_number":7421,"context_line":"                    header_list\u003dexp_seen_header_list, no_heads\u003dTrue)"},{"line_number":7422,"context_line":""},{"line_number":7423,"context_line":"            self.assertEqual(seen_headers, expected_headers)"},{"line_number":7424,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"b9160de2_9ad4103b","line":7421,"updated":"2024-07-13 02:22:10.000000000","message":"is `no_heads` really *needed* - I don\u0027t typically like re-usable test infra to have too many strings that are only pulled in one place.","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b756ed925c28f037601609fd1c67a3f2a7676dca","unresolved":false,"context_lines":[{"line_number":7418,"context_line":"                seen_headers \u003d self._gather_x_container_headers("},{"line_number":7419,"context_line":"                    controller.PUT, req,"},{"line_number":7420,"context_line":"                    201, 201, 201,  # PUT PUT PUT"},{"line_number":7421,"context_line":"                    header_list\u003dexp_seen_header_list, no_heads\u003dTrue)"},{"line_number":7422,"context_line":""},{"line_number":7423,"context_line":"            self.assertEqual(seen_headers, expected_headers)"},{"line_number":7424,"context_line":""}],"source_content_type":"text/x-python","patch_set":16,"id":"419d2c0a_3e921c7a","line":7421,"in_reply_to":"b9160de2_9ad4103b","updated":"2024-07-15 13:07:51.000000000","message":"addressed in 924108: trivial: refactor _get_update_target | https://review.opendev.org/c/openstack/swift/+/924108","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1b3fe3d864a3b66f07500ffbcba120f104344834","unresolved":true,"context_lines":[{"line_number":7602,"context_line":"            controller.PUT, req,"},{"line_number":7603,"context_line":"            200, 200, 201, 201, 201,   # HEAD HEAD PUT PUT PUT"},{"line_number":7604,"context_line":"            header_list\u003d(\u0027X-Delete-At-Host\u0027, \u0027X-Delete-At-Device\u0027,"},{"line_number":7605,"context_line":"                         \u0027X-Delete-At-Partition\u0027, \u0027X-Delete-At-Container\u0027))"},{"line_number":7606,"context_line":""},{"line_number":7607,"context_line":"        self.assertEqual(seen_headers, ["},{"line_number":7608,"context_line":"            {\u0027X-Delete-At-Host\u0027: \u002710.0.0.0:1000\u0027,"}],"source_content_type":"text/x-python","patch_set":16,"id":"c77397e4_f9faff04","line":7605,"updated":"2024-07-13 02:22:10.000000000","message":"so I like that you updated the default \"header_list\" - it\u0027s quite nice to see so many \"X-Container-Root-Db-State: unsharded\" in these diffs - but where do you draw the line at which tests should get updated to demonstrate we\u0027re sending a new backend header?  maybe a `_gather_x_container_x_delete_headers` would be better for this test.","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b756ed925c28f037601609fd1c67a3f2a7676dca","unresolved":false,"context_lines":[{"line_number":7602,"context_line":"            controller.PUT, req,"},{"line_number":7603,"context_line":"            200, 200, 201, 201, 201,   # HEAD HEAD PUT PUT PUT"},{"line_number":7604,"context_line":"            header_list\u003d(\u0027X-Delete-At-Host\u0027, \u0027X-Delete-At-Device\u0027,"},{"line_number":7605,"context_line":"                         \u0027X-Delete-At-Partition\u0027, \u0027X-Delete-At-Container\u0027))"},{"line_number":7606,"context_line":""},{"line_number":7607,"context_line":"        self.assertEqual(seen_headers, ["},{"line_number":7608,"context_line":"            {\u0027X-Delete-At-Host\u0027: \u002710.0.0.0:1000\u0027,"}],"source_content_type":"text/x-python","patch_set":16,"id":"d33c1f8e_def83841","line":7605,"in_reply_to":"c77397e4_f9faff04","updated":"2024-07-15 13:07:51.000000000","message":"addressed in 924108: trivial: refactor _get_update_target | https://review.opendev.org/c/openstack/swift/+/924108","commit_id":"8f2a66c5440efc4352fb150fd644c9cc19e8c821"}]}
