)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"4b77f30265c72808d43c211580e7ca028fd72ce6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"06179a85_dc1f34eb","updated":"2025-08-11 17:20:11.000000000","message":"When I revert most of ssync_receiver I can get a traceback that looks suspiciously similar to the bug report:\n\n```\nvagrant@saio:~$ pytest swift/test/unit/obj/test_ssync_receiver.py::TestReceiver::test_UPDATES_timeout_reading_PUT_subreq_input_1\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d test session starts \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\nplatform linux -- Python 3.10.12, pytest-8.3.5, pluggy-1.5.0 -- /usr/bin/python3\ncachedir: .pytest_cache\nrootdir: /home/vagrant/swift\nconfigfile: tox.ini\nplugins: subtests-0.14.2, cov-6.0.0\ncollected 1 item                                                                                                                                                                                                                                       \n\nswift/test/unit/obj/test_ssync_receiver.py::TestReceiver::test_UPDATES_timeout_reading_PUT_subreq_input_1 FAILED                                                                                                                                 [100%]\n\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d FAILURES \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n_____________________________________________________________________________________________ TestReceiver.test_UPDATES_timeout_reading_PUT_subreq_input_1 _____________________________________________________________________________________________\n\nself \u003d \u003ctest.unit.obj.test_ssync_receiver.TestReceiver testMethod\u003dtest_UPDATES_timeout_reading_PUT_subreq_input_1\u003e\n\n    def test_UPDATES_timeout_reading_PUT_subreq_input_1(self):\n        # timeout reading from wsgi input part way through a PUT subreq body\n        body_chunks \u003d [\n            \u0027:MISSING_CHECK: START\\r\\n\u0027,\n            \u0027:MISSING_CHECK: END\\r\\n\u0027,\n            \u0027:UPDATES: START\\r\\n\u0027,\n            \u0027PUT /a/c/o\\r\\nContent-Length: 28\\r\\n\\r\\n\u0027,\n            \u0027body_chunk_one\u0027,\n            \u0027body_chunk_two\u0027,\n            \u0027:UPDATES: END\\r\\n\u0027,\n            \u0027\u0027\n        ]\n        chunked_body \u003d \u0027\u0027.join([\n            \u0027%x\\r\\n%s\\r\\n\u0027 % (len(line), line) for line in body_chunks\n        ])\n        req \u003d swob.Request.blank(\n            \u0027/device/partition\u0027,\n            environ\u003d{\u0027REQUEST_METHOD\u0027: \u0027SSYNC\u0027},\n            body\u003dchunked_body)\n        req.remote_addr \u003d \u00272.3.4.5\u0027\n        slow_down_index \u003d chunked_body.find(\u0027chunk_one\u0027)\n        slow_io \u003d SlowBytesIO(req.body, sleep_index\u003dslow_down_index)\n        wsgi_input \u003d eventlet.wsgi.Input(\n            rfile\u003dslow_io, content_length\u003d123, sock\u003dmock.MagicMock(),\n            chunked_input\u003dTrue)\n        req.environ[\u0027wsgi.input\u0027] \u003d wsgi_input\n        controller \u003d FakeController(self.conf, logger\u003dself.logger)\n        controller.client_timeout \u003d 0.01\n        with mock.patch.object(\n                ssync_receiver.eventlet.greenio, \u0027shutdown_safe\u0027) as \\\n                mock_shutdown_safe:\n            resp \u003d req.get_response(controller)\n            resp_body_lines \u003d self.body_lines(resp.body)\n        self.assertEqual(resp.status_int, 200)\n\u003e       self.assertEqual(\n            [b\u0027:MISSING_CHECK: START\u0027,\n             b\u0027:MISSING_CHECK: END\u0027,\n             b\":ERROR: 408 \u00270.01 seconds: PUT /a/c/o\u0027\"], resp_body_lines)\nE       AssertionError: Lists differ: [b\u0027:M[46 chars]b\":ERROR: 408 \u00270.01 seconds: PUT /a/c/o\u0027\"] !\u003d [b\u0027:M[46 chars]b\":ERROR: 0 \u0027not enough values to unpack (expected 2, got 1)\u0027\"]\nE       \nE       First differing element 2:\nE       b\":ERROR: 408 \u00270.01 seconds: PUT /a/c/o\u0027\"\nE       b\":ERROR: 0 \u0027not enough values to unpack (expected 2, got 1)\u0027\"\nE       \nE         [b\u0027:MISSING_CHECK: START\u0027,\nE          b\u0027:MISSING_CHECK: END\u0027,\nE       -  b\":ERROR: 408 \u00270.01 seconds: PUT /a/c/o\u0027\"]\nE       +  b\":ERROR: 0 \u0027not enough values to unpack (expected 2, got 1)\u0027\"]\n\nswift/test/unit/obj/test_ssync_receiver.py:1430: AssertionError\n----------------------------------------------------------------------------------------------------------------- Captured stdout call -----------------------------------------------------------------------------------------------------------------\ntest DEBUG: Labeled statsd mode: disabled (test)\ntest DEBUG: Labeled statsd mode: disabled (test)\ntest ERROR: ERROR __call__ error with PUT /device/partition/a/c/o : MessageTimeout (0.01s) updates content\ntest WARNING: ssync subrequest failed with 500: PUT /device/partition/a/c/o (b\u0027Traceback (most recent call last):\\n  File \"/home/vagrant/swift/swift/obj/server.py\", line 1417, in __call__\\n    res \u003d getattr(self, req.method)(req)\\n  File \"/home/vagrant/swift/test/unit/obj/test_ssync_receiver.py\", line 63, in PUT\\n    b\\\u0027\\\u0027.join(req.environ[\\\u0027wsgi.input\\\u0027])\\n  File \"/home/vagrant/swift/swift/common/utils/__init__.py\", line 500, in __next__\\n    return next(self.iterator)\\n  File \"/home/vagrant/swift/swift/obj/ssync_receiver.py\", line 599, in subreq_iter\\n    chunk \u003d self.fp.read(\\n  File \"/home/vagrant/.local/lib/python3.10/site-packages/eventlet/wsgi.py\", line 212, in read\\n    return self._chunked_read(self.rfile, length)\\n  File \"/home/vagrant/.local/lib/python3.10/site-packages/eventlet/wsgi.py\", line 180, in _chunked_read\\n    data \u003d reader(maxreadlen)\\n  File \"/home/vagrant/swift/test/unit/obj/test_ssync_receiver.py\", line 110, in read\\n    return self._read(size, False)\\n  File \"/home/vagrant/swift/test/unit/obj/test_ssync_receiver.py\", line 94, in _read\\n    eventlet.sleep(self.sleep_time)\\n  File \"/home/vagrant/.local/lib/python3.10/site-packages/eventlet/greenthread.py\", line 45, in sleep\\n    hub.switch()\\n  File \"/home/vagrant/.local/lib/python3.10/site-packages/eventlet/hubs/hub.py\", line 310, in switch\\n    return self.greenlet.switch()\\nswift.common.exceptions.MessageTimeout: 0.01 seconds: updates content\\n\u0027)\ntest ERROR: 2.3.4.5/device/partition EXCEPTION in ssync.Receiver: \nTraceback (most recent call last):\n  File \"/home/vagrant/swift/swift/obj/ssync_receiver.py\", line 272, in __call__\n    for data in self.updates():\n  File \"/home/vagrant/swift/swift/obj/ssync_receiver.py\", line 551, in updates\n    method, path \u003d swob.bytes_to_wsgi(line.strip()).split(\u0027 \u0027, 1)\nValueError: not enough values to unpack (expected 2, got 1)\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d short test summary info \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\nFAILED swift/test/unit/obj/test_ssync_receiver.py::TestReceiver::test_UPDATES_timeout_reading_PUT_subreq_input_1 - AssertionError: Lists differ: [b\u0027:M[46 chars]b\":ERROR: 408 \u00270.01 seconds: PUT /a/c/o\u0027\"] !\u003d [b\u0027:M[46 chars]b\":ERROR: 0 \u0027not enough values to unpack (expected 2, got 1)\u0027\"]\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d 1 failed in 0.36s \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\n```\n\nI think the description of the problem (truncated line w/o newline at the end) seems reasonable given the existing code.  The encapsulation of the message timeout handling seems like a reasonable enough abstraction given that the parsing code doesn\u0027t want to have to think about message framing issues.","commit_id":"1dc3307eaf0457e59337ca9a153c12aaade6696b"}],"swift/obj/ssync_receiver.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a0804e180d6397fcc33e5da1bec920210855221e","unresolved":true,"context_lines":[{"line_number":112,"context_line":"        self.timeout \u003d timeout"},{"line_number":113,"context_line":"        self.context \u003d context"},{"line_number":114,"context_line":"        # TODO: busted? closed? errored?"},{"line_number":115,"context_line":"        self.exception \u003d None"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    def __iter__(self):"},{"line_number":118,"context_line":"        return self"}],"source_content_type":"text/x-python","patch_set":3,"id":"518fe505_d6bb7ca8","line":115,"updated":"2025-07-07 14:59:47.000000000","message":"I don\u0027t like that this only annotates the subreq iter - ther\u0027s nothing to mark the underlying wsgi input as also being unusable","commit_id":"4e94fc75d25075d088afc26db71e2b56afdd3513"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fca0866029bd729a919f88aecee04d9fb7514315","unresolved":true,"context_lines":[{"line_number":112,"context_line":"        self.timeout \u003d timeout"},{"line_number":113,"context_line":"        self.context \u003d context"},{"line_number":114,"context_line":"        # TODO: busted? closed? errored?"},{"line_number":115,"context_line":"        self.exception \u003d None"},{"line_number":116,"context_line":""},{"line_number":117,"context_line":"    def __iter__(self):"},{"line_number":118,"context_line":"        return self"}],"source_content_type":"text/x-python","patch_set":3,"id":"7d55fc6c_8130dccf","line":115,"in_reply_to":"518fe505_d6bb7ca8","updated":"2025-07-07 17:14:37.000000000","message":"Makes me wish eventlet\u0027s `Input` had a `close` method...\n\nMaybe *that\u0027s* what the real solution for https://review.opendev.org/c/openstack/swift/+/799866 should look like -- if a WSGI app wants to close the connection, if should close the `wsgi.input` given to it, which should then go all the way down to the `rfile` so eventlet *can\u0027t* try to read a pipelined request (nor even discard whatever extra input it thinks will be there)....\n\nOf course, doing it right would require an eventlet patch :-/","commit_id":"4e94fc75d25075d088afc26db71e2b56afdd3513"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ebb30bc696860384d66237e6fc476b6edd297d71","unresolved":true,"context_lines":[{"line_number":132,"context_line":"            return chunk"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        except BaseException as exc:"},{"line_number":135,"context_line":"            # TODO: *all* exceptions? definitely Timeouts"},{"line_number":136,"context_line":"            self.exception \u003d exc"},{"line_number":137,"context_line":"            raise"},{"line_number":138,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"39304843_40861c42","line":135,"updated":"2025-07-03 19:01:31.000000000","message":"Yeah, all seems safest. _Maybe_ it\u0027d be better as `except (Exception, Timeout) as exc:` like we do in some other places?","commit_id":"4e94fc75d25075d088afc26db71e2b56afdd3513"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"511e33338eae2ff0ba5533acefc856174c340fd3","unresolved":true,"context_lines":[{"line_number":132,"context_line":"            return chunk"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        except BaseException as exc:"},{"line_number":135,"context_line":"            # TODO: *all* exceptions? definitely Timeouts"},{"line_number":136,"context_line":"            self.exception \u003d exc"},{"line_number":137,"context_line":"            raise"},{"line_number":138,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"46af0c01_177a5238","line":135,"in_reply_to":"39304843_40861c42","updated":"2025-07-04 15:38:35.000000000","message":"agree, clearer that way.","commit_id":"4e94fc75d25075d088afc26db71e2b56afdd3513"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b0f4810a6bda74c45ff2677bd0c2ba1b3a9619d6","unresolved":false,"context_lines":[{"line_number":132,"context_line":"            return chunk"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"        except BaseException as exc:"},{"line_number":135,"context_line":"            # TODO: *all* exceptions? definitely Timeouts"},{"line_number":136,"context_line":"            self.exception \u003d exc"},{"line_number":137,"context_line":"            raise"},{"line_number":138,"context_line":""}],"source_content_type":"text/x-python","patch_set":3,"id":"098832af_8f04b0db","line":135,"in_reply_to":"46af0c01_177a5238","updated":"2025-08-04 15:50:57.000000000","message":"Done","commit_id":"4e94fc75d25075d088afc26db71e2b56afdd3513"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"a0804e180d6397fcc33e5da1bec920210855221e","unresolved":true,"context_lines":[{"line_number":581,"context_line":"            # The subreq may have failed, but we want to read the rest of the"},{"line_number":582,"context_line":"            # body from the remote side so we can continue on with the next"},{"line_number":583,"context_line":"            # subreq."},{"line_number":584,"context_line":"            if subreq_iter and subreq_iter.exception:"},{"line_number":585,"context_line":"                raise Exception(str(subreq_iter.exception))"},{"line_number":586,"context_line":"            for junk in subreq.environ[\u0027wsgi.input\u0027]:"},{"line_number":587,"context_line":"                pass"}],"source_content_type":"text/x-python","patch_set":3,"id":"9d5e7ac1_4ca6d23d","line":584,"range":{"start_line":584,"start_character":12,"end_line":584,"end_character":52},"updated":"2025-07-07 14:59:47.000000000","message":"I don\u0027t like that the caller has check that the subreq iter is still ok before continuing to use the underlying wsgi input, rather than the underlying wsgi input  just blowing up on next use","commit_id":"4e94fc75d25075d088afc26db71e2b56afdd3513"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b0f4810a6bda74c45ff2677bd0c2ba1b3a9619d6","unresolved":false,"context_lines":[{"line_number":581,"context_line":"            # The subreq may have failed, but we want to read the rest of the"},{"line_number":582,"context_line":"            # body from the remote side so we can continue on with the next"},{"line_number":583,"context_line":"            # subreq."},{"line_number":584,"context_line":"            if subreq_iter and subreq_iter.exception:"},{"line_number":585,"context_line":"                raise Exception(str(subreq_iter.exception))"},{"line_number":586,"context_line":"            for junk in subreq.environ[\u0027wsgi.input\u0027]:"},{"line_number":587,"context_line":"                pass"}],"source_content_type":"text/x-python","patch_set":3,"id":"8227974b_dca796d0","line":584,"range":{"start_line":584,"start_character":12,"end_line":584,"end_character":52},"in_reply_to":"9d5e7ac1_4ca6d23d","updated":"2025-08-04 15:50:57.000000000","message":"Done","commit_id":"4e94fc75d25075d088afc26db71e2b56afdd3513"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"ebb30bc696860384d66237e6fc476b6edd297d71","unresolved":true,"context_lines":[{"line_number":582,"context_line":"            # body from the remote side so we can continue on with the next"},{"line_number":583,"context_line":"            # subreq."},{"line_number":584,"context_line":"            if subreq_iter and subreq_iter.exception:"},{"line_number":585,"context_line":"                raise Exception(str(subreq_iter.exception))"},{"line_number":586,"context_line":"            for junk in subreq.environ[\u0027wsgi.input\u0027]:"},{"line_number":587,"context_line":"                pass"},{"line_number":588,"context_line":"            if updates % 5 \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9bd5a3e3_ad3850e9","line":585,"updated":"2025-07-03 19:01:31.000000000","message":"How do things look if we just\n```\nraise subreq_iter.exception\n```\n?","commit_id":"4e94fc75d25075d088afc26db71e2b56afdd3513"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b0f4810a6bda74c45ff2677bd0c2ba1b3a9619d6","unresolved":false,"context_lines":[{"line_number":582,"context_line":"            # body from the remote side so we can continue on with the next"},{"line_number":583,"context_line":"            # subreq."},{"line_number":584,"context_line":"            if subreq_iter and subreq_iter.exception:"},{"line_number":585,"context_line":"                raise Exception(str(subreq_iter.exception))"},{"line_number":586,"context_line":"            for junk in subreq.environ[\u0027wsgi.input\u0027]:"},{"line_number":587,"context_line":"                pass"},{"line_number":588,"context_line":"            if updates % 5 \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":3,"id":"daf42f2a_a1ac5918","line":585,"in_reply_to":"9aad406a_1a7b9f44","updated":"2025-08-04 15:50:57.000000000","message":"Done","commit_id":"4e94fc75d25075d088afc26db71e2b56afdd3513"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"511e33338eae2ff0ba5533acefc856174c340fd3","unresolved":true,"context_lines":[{"line_number":582,"context_line":"            # body from the remote side so we can continue on with the next"},{"line_number":583,"context_line":"            # subreq."},{"line_number":584,"context_line":"            if subreq_iter and subreq_iter.exception:"},{"line_number":585,"context_line":"                raise Exception(str(subreq_iter.exception))"},{"line_number":586,"context_line":"            for junk in subreq.environ[\u0027wsgi.input\u0027]:"},{"line_number":587,"context_line":"                pass"},{"line_number":588,"context_line":"            if updates % 5 \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":3,"id":"9aad406a_1a7b9f44","line":585,"in_reply_to":"9bd5a3e3_ad3850e9","updated":"2025-07-04 15:38:35.000000000","message":"better! it\u0027s then logged as a TIMEOUT","commit_id":"4e94fc75d25075d088afc26db71e2b56afdd3513"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3ac6d1140051ef6571f617de67ebc22c9261e6f3","unresolved":true,"context_lines":[{"line_number":359,"context_line":"        with exceptions.MessageTimeout("},{"line_number":360,"context_line":"                self.app.client_timeout, context):"},{"line_number":361,"context_line":"            try:"},{"line_number":362,"context_line":"                line \u003d self.input.readline(self.app.network_chunk_size)"},{"line_number":363,"context_line":"                if line and not line.endswith(b\u0027\\n\u0027):"},{"line_number":364,"context_line":"                    # Everywhere we would call readline, we should always get"},{"line_number":365,"context_line":"                    # a clean end-of-line as we should be reading"}],"source_content_type":"text/x-python","patch_set":4,"id":"863d865e_62757572","line":362,"range":{"start_line":362,"start_character":23,"end_line":362,"end_character":42},"updated":"2025-07-28 02:32:16.000000000","message":"So that should be an `AttributeError` -- the `SsyncInputProxy` has a `read_line` but no `readline`. Which presumably means that nothing uses this `_readline` any more.","commit_id":"8ece3061d4889555919bc2da06e2f0574c64a442"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b0f4810a6bda74c45ff2677bd0c2ba1b3a9619d6","unresolved":false,"context_lines":[{"line_number":359,"context_line":"        with exceptions.MessageTimeout("},{"line_number":360,"context_line":"                self.app.client_timeout, context):"},{"line_number":361,"context_line":"            try:"},{"line_number":362,"context_line":"                line \u003d self.input.readline(self.app.network_chunk_size)"},{"line_number":363,"context_line":"                if line and not line.endswith(b\u0027\\n\u0027):"},{"line_number":364,"context_line":"                    # Everywhere we would call readline, we should always get"},{"line_number":365,"context_line":"                    # a clean end-of-line as we should be reading"}],"source_content_type":"text/x-python","patch_set":4,"id":"e65fbc0a_7896a877","line":362,"range":{"start_line":362,"start_character":23,"end_line":362,"end_character":42},"in_reply_to":"863d865e_62757572","updated":"2025-08-04 15:50:57.000000000","message":"Done","commit_id":"8ece3061d4889555919bc2da06e2f0574c64a442"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fca0866029bd729a919f88aecee04d9fb7514315","unresolved":true,"context_lines":[{"line_number":480,"context_line":"        have to read while it writes to ensure network buffers don\u0027t"},{"line_number":481,"context_line":"        fill up and block everything."},{"line_number":482,"context_line":"        \"\"\""},{"line_number":483,"context_line":"        line \u003d self.input.read_line(\u0027missing_check start\u0027)"},{"line_number":484,"context_line":"        if not line:"},{"line_number":485,"context_line":"            # Guess they hung up"},{"line_number":486,"context_line":"            raise SsyncClientDisconnected"}],"source_content_type":"text/x-python","patch_set":4,"id":"a678abd5_d6ebb338","line":483,"updated":"2025-07-07 17:14:37.000000000","message":"Do we really want to change all of these? Why not continue to use `self._readline` (which wraps `self.input.read_line`)? Does anything still use `self._readline` now?","commit_id":"8ece3061d4889555919bc2da06e2f0574c64a442"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3ac6d1140051ef6571f617de67ebc22c9261e6f3","unresolved":true,"context_lines":[{"line_number":480,"context_line":"        have to read while it writes to ensure network buffers don\u0027t"},{"line_number":481,"context_line":"        fill up and block everything."},{"line_number":482,"context_line":"        \"\"\""},{"line_number":483,"context_line":"        line \u003d self.input.read_line(\u0027missing_check start\u0027)"},{"line_number":484,"context_line":"        if not line:"},{"line_number":485,"context_line":"            # Guess they hung up"},{"line_number":486,"context_line":"            raise SsyncClientDisconnected"}],"source_content_type":"text/x-python","patch_set":4,"id":"fadfc7a4_197fa13f","line":483,"in_reply_to":"a678abd5_d6ebb338","updated":"2025-07-28 02:32:16.000000000","message":"It took me trying to put this back to realize that `read_line` has a very different semantic from `readline`...","commit_id":"8ece3061d4889555919bc2da06e2f0574c64a442"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b0f4810a6bda74c45ff2677bd0c2ba1b3a9619d6","unresolved":false,"context_lines":[{"line_number":480,"context_line":"        have to read while it writes to ensure network buffers don\u0027t"},{"line_number":481,"context_line":"        fill up and block everything."},{"line_number":482,"context_line":"        \"\"\""},{"line_number":483,"context_line":"        line \u003d self.input.read_line(\u0027missing_check start\u0027)"},{"line_number":484,"context_line":"        if not line:"},{"line_number":485,"context_line":"            # Guess they hung up"},{"line_number":486,"context_line":"            raise SsyncClientDisconnected"}],"source_content_type":"text/x-python","patch_set":4,"id":"dfd11f21_e6a19673","line":483,"in_reply_to":"fadfc7a4_197fa13f","updated":"2025-08-04 15:50:57.000000000","message":"Done","commit_id":"8ece3061d4889555919bc2da06e2f0574c64a442"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"3ac6d1140051ef6571f617de67ebc22c9261e6f3","unresolved":true,"context_lines":[{"line_number":599,"context_line":"            elif method \u003d\u003d \u0027PUT\u0027:"},{"line_number":600,"context_line":"                if content_length is None:"},{"line_number":601,"context_line":"                    raise Exception(\u0027No content-length sent for %s\u0027 % context)"},{"line_number":602,"context_line":"                subreq_iter \u003d self.input.make_subreq_iter("},{"line_number":603,"context_line":"                    context, content_length)"},{"line_number":604,"context_line":"                subreq.environ[\u0027wsgi.input\u0027] \u003d utils.FileLikeIter("},{"line_number":605,"context_line":"                    subreq_iter)"},{"line_number":606,"context_line":"            else:"},{"line_number":607,"context_line":"                raise Exception(\u0027Invalid subrequest method %s\u0027 % method)"},{"line_number":608,"context_line":"            subreq.headers[\u0027X-Backend-Storage-Policy-Index\u0027] \u003d int(self.policy)"}],"source_content_type":"text/x-python","patch_set":4,"id":"9ae2e1b5_0d0a6bd8","line":605,"range":{"start_line":602,"start_character":16,"end_line":605,"end_character":32},"updated":"2025-07-28 02:32:16.000000000","message":"This makes me feel like the input should just offer a `make_subreq_wsgi_input`","commit_id":"8ece3061d4889555919bc2da06e2f0574c64a442"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b0f4810a6bda74c45ff2677bd0c2ba1b3a9619d6","unresolved":false,"context_lines":[{"line_number":599,"context_line":"            elif method \u003d\u003d \u0027PUT\u0027:"},{"line_number":600,"context_line":"                if content_length is None:"},{"line_number":601,"context_line":"                    raise Exception(\u0027No content-length sent for %s\u0027 % context)"},{"line_number":602,"context_line":"                subreq_iter \u003d self.input.make_subreq_iter("},{"line_number":603,"context_line":"                    context, content_length)"},{"line_number":604,"context_line":"                subreq.environ[\u0027wsgi.input\u0027] \u003d utils.FileLikeIter("},{"line_number":605,"context_line":"                    subreq_iter)"},{"line_number":606,"context_line":"            else:"},{"line_number":607,"context_line":"                raise Exception(\u0027Invalid subrequest method %s\u0027 % method)"},{"line_number":608,"context_line":"            subreq.headers[\u0027X-Backend-Storage-Policy-Index\u0027] \u003d int(self.policy)"}],"source_content_type":"text/x-python","patch_set":4,"id":"4b21a3b0_8f9e2aa2","line":605,"range":{"start_line":602,"start_character":16,"end_line":605,"end_character":32},"in_reply_to":"9ae2e1b5_0d0a6bd8","updated":"2025-08-04 15:50:57.000000000","message":"Done","commit_id":"8ece3061d4889555919bc2da06e2f0574c64a442"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"fca0866029bd729a919f88aecee04d9fb7514315","unresolved":true,"context_lines":[{"line_number":632,"context_line":"                    (failures, successes))"},{"line_number":633,"context_line":"            # The subreq may have failed, but we want to read the rest of the"},{"line_number":634,"context_line":"            # body from the remote side so we can continue on with the next"},{"line_number":635,"context_line":"            # subreq."},{"line_number":636,"context_line":"            for junk in subreq.environ[\u0027wsgi.input\u0027]:"},{"line_number":637,"context_line":"                pass"},{"line_number":638,"context_line":"            if updates % 5 \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":4,"id":"721e0a2c_5569fdc2","line":635,"updated":"2025-07-07 17:14:37.000000000","message":"We probably ought to update the comment here; something like\n\n\u003e so we can either detect a broken input or continue on with the next subreq.","commit_id":"8ece3061d4889555919bc2da06e2f0574c64a442"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"b0f4810a6bda74c45ff2677bd0c2ba1b3a9619d6","unresolved":false,"context_lines":[{"line_number":632,"context_line":"                    (failures, successes))"},{"line_number":633,"context_line":"            # The subreq may have failed, but we want to read the rest of the"},{"line_number":634,"context_line":"            # body from the remote side so we can continue on with the next"},{"line_number":635,"context_line":"            # subreq."},{"line_number":636,"context_line":"            for junk in subreq.environ[\u0027wsgi.input\u0027]:"},{"line_number":637,"context_line":"                pass"},{"line_number":638,"context_line":"            if updates % 5 \u003d\u003d 0:"}],"source_content_type":"text/x-python","patch_set":4,"id":"770c4c7e_b2b9f506","line":635,"in_reply_to":"721e0a2c_5569fdc2","updated":"2025-08-04 15:50:57.000000000","message":"Done","commit_id":"8ece3061d4889555919bc2da06e2f0574c64a442"}]}
