)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"98b568b71612afd3bd9a06db8285f3c0d58276fc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"2048eb6c_34e6c133","updated":"2023-05-17 14:26:02.000000000","message":"Why not just always check the modulo in incr() (also call it \"fairness()\" or \"poke()\" or something - why expose the detail of incrementation)? That maybe_sleep() being separate is just some kind of weird hold-over from the old code. I understand that you\u0027re guarding against any possible regression with this, but the result is a bit klunky. The inline question about fast_forward is an evidence of it. Maybe add the incr() in there. Be axiomatic: \"we read the chunk, we maybe-sleep\". What do you think?","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b9f0ad790ad55bad41b69e1ae8103aacd43a2724","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"85a1ff49_7d148f87","updated":"2023-05-17 16:55:25.000000000","message":"seems right in spirit, I would have loved to see a \"sleepy iterator\" kind of interface but this is probably a good start at fixing the problem (which is pretty bad)","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"805b19e9541d50db9ba015a8bd06d27ee23e6392","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"a51c6613_a3ea2d87","in_reply_to":"2048eb6c_34e6c133","updated":"2023-05-17 16:19:51.000000000","message":"I agree it\u0027s klunky.\n\nI wanted to make an *exact* replacement, but now I have at least got a fix I\u0027ll look at making it more elegant.","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"be7a0a8662502fa55787d85e16269e4df184fd39","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"1886e614_4aa7d14b","updated":"2023-05-18 18:11:41.000000000","message":"OK, I went for the wrapping iterator idea, but it does subtley modify when the sleeps() occur. However, the original behaviour of some arbitrary \"hand-waving\" rate of sleeps is preserved.\n\nI\u0027ve still not written direct tests that the PUT and GET paths *do* cooperatively sleep.","commit_id":"3a7a8bd2173673176406d6c04c2503fa67b4c970"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"616b638a3eebbf68198f6e32b8d9f765f95b7ff3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"adae17d4_a0fa8408","updated":"2023-05-18 18:52:51.000000000","message":"this is looking pretty slick!  This new primative might end up being a pretty easy pattern to carry forward - kudos!\n\nIf we could figure out how to assert every ECAppIter we return and wsgi_input we read is at some level wrapping a cooperative iter we might even be able to avoid chasing this problem around.","commit_id":"975bf0e6677300485b33aca5471dcff75b0c2c71"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"2ed681ca09ec4cbf54c0ca9e074565434f8d4ded","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"d15d4170_7a5a2a2e","updated":"2023-05-19 22:12:07.000000000","message":"I know Alistair was a little worried about tests:\n\n\u003e I\u0027ve still not written direct tests that the PUT and GET paths do cooperatively sleep.\n\nBut it seems like we don\u0027t have tests for the GET path *either*... and the patch that first introduced the sleep (https://opendev.org/openstack/swift/commit/a4e25d6da8d007051b3b0575de47338e210d4315) didn\u0027t even *touch* tests... so... I don\u0027t think it\u0027s worth holding this up over it.","commit_id":"aa96cb3dc675415f48d8bb2f8b61a4f394759f53"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"e8ac70be7fe511cb81d672cbf995a20b857eb76e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"f3675d7f_aa94e792","updated":"2023-05-18 19:41:40.000000000","message":"Tim\u0027s change was pretty surgical.","commit_id":"aa96cb3dc675415f48d8bb2f8b61a4f394759f53"}],"swift/common/utils/__init__.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b9f0ad790ad55bad41b69e1ae8103aacd43a2724","unresolved":true,"context_lines":[{"line_number":6342,"context_line":"    def incr(self, maybe_sleep\u003dFalse):"},{"line_number":6343,"context_line":"        self.count +\u003d 1"},{"line_number":6344,"context_line":"        if maybe_sleep:"},{"line_number":6345,"context_line":"            self.maybe_sleep()"},{"line_number":6346,"context_line":""},{"line_number":6347,"context_line":"    def maybe_sleep(self):"},{"line_number":6348,"context_line":"        if self.count \u003e\u003d 5:"}],"source_content_type":"text/x-python","patch_set":1,"id":"6df84782_9accec2c","line":6345,"updated":"2023-05-17 16:55:25.000000000","message":"It\u0027s not obvious to me why we need a boolean kwarg to call a public method inside another public method.  It would seem totally reasonable to if a caller wanted to sleeper.incr(); sleeper.maybe_sleep().  Alternatively, it might be a reasonable goal to try and have only one public method - where incr *is* \"maybe_sleep\" and will always call sleep when it needs to.","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"46e29ac095f77787152dac83811e35107a31ca04","unresolved":true,"context_lines":[{"line_number":6342,"context_line":"    def incr(self, maybe_sleep\u003dFalse):"},{"line_number":6343,"context_line":"        self.count +\u003d 1"},{"line_number":6344,"context_line":"        if maybe_sleep:"},{"line_number":6345,"context_line":"            self.maybe_sleep()"},{"line_number":6346,"context_line":""},{"line_number":6347,"context_line":"    def maybe_sleep(self):"},{"line_number":6348,"context_line":"        if self.count \u003e\u003d 5:"}],"source_content_type":"text/x-python","patch_set":1,"id":"f55285d6_84a69599","line":6345,"in_reply_to":"6df84782_9accec2c","updated":"2023-05-18 15:44:45.000000000","message":"I was miffed about having 2 methods, so I ended up writing it all badly :/","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"be7a0a8662502fa55787d85e16269e4df184fd39","unresolved":false,"context_lines":[{"line_number":6342,"context_line":"    def incr(self, maybe_sleep\u003dFalse):"},{"line_number":6343,"context_line":"        self.count +\u003d 1"},{"line_number":6344,"context_line":"        if maybe_sleep:"},{"line_number":6345,"context_line":"            self.maybe_sleep()"},{"line_number":6346,"context_line":""},{"line_number":6347,"context_line":"    def maybe_sleep(self):"},{"line_number":6348,"context_line":"        if self.count \u003e\u003d 5:"}],"source_content_type":"text/x-python","patch_set":1,"id":"e0faab2f_ff524009","line":6345,"in_reply_to":"f55285d6_84a69599","updated":"2023-05-18 18:11:41.000000000","message":"Done","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"b9f0ad790ad55bad41b69e1ae8103aacd43a2724","unresolved":true,"context_lines":[{"line_number":6345,"context_line":"            self.maybe_sleep()"},{"line_number":6346,"context_line":""},{"line_number":6347,"context_line":"    def maybe_sleep(self):"},{"line_number":6348,"context_line":"        if self.count \u003e\u003d 5:"},{"line_number":6349,"context_line":"            self.count \u003d 0"},{"line_number":6350,"context_line":"            sleep()"}],"source_content_type":"text/x-python","patch_set":1,"id":"7d180538_5a2f681f","line":6348,"updated":"2023-05-17 16:55:25.000000000","message":"maybe make the magic number a class attribute or something?","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"46e29ac095f77787152dac83811e35107a31ca04","unresolved":false,"context_lines":[{"line_number":6345,"context_line":"            self.maybe_sleep()"},{"line_number":6346,"context_line":""},{"line_number":6347,"context_line":"    def maybe_sleep(self):"},{"line_number":6348,"context_line":"        if self.count \u003e\u003d 5:"},{"line_number":6349,"context_line":"            self.count \u003d 0"},{"line_number":6350,"context_line":"            sleep()"}],"source_content_type":"text/x-python","patch_set":1,"id":"ecf56df6_71d4e22e","line":6348,"in_reply_to":"56ddebe3_565cc3ad","updated":"2023-05-18 15:44:45.000000000","message":"Done\n\n@Tim spotted my to-and-fro on this","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"8e15262fa9ce0903ff49e4984d3130ee2b431af1","unresolved":true,"context_lines":[{"line_number":6345,"context_line":"            self.maybe_sleep()"},{"line_number":6346,"context_line":""},{"line_number":6347,"context_line":"    def maybe_sleep(self):"},{"line_number":6348,"context_line":"        if self.count \u003e\u003d 5:"},{"line_number":6349,"context_line":"            self.count \u003d 0"},{"line_number":6350,"context_line":"            sleep()"}],"source_content_type":"text/x-python","patch_set":1,"id":"56ddebe3_565cc3ad","line":6348,"in_reply_to":"7d180538_5a2f681f","updated":"2023-05-17 21:00:03.000000000","message":"Looks like we\u0027re already half-way there with the `__slots__`...","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"54d61832474c0914196a6d222d00e25ee6513ec8","unresolved":true,"context_lines":[{"line_number":6343,"context_line":"    every 5 chunks, depending on how blocking our network IO is; the explicit"},{"line_number":6344,"context_line":"    sleep here simply provides a lower bound on the rate of trampolining."},{"line_number":6345,"context_line":""},{"line_number":6346,"context_line":"    :param iterable: iterator to wrap; this may be ``None``, in which case this"},{"line_number":6347,"context_line":"        iterator will always yield ``None``."},{"line_number":6348,"context_line":"    :param period: number of items yielded from this iterator between calls to"},{"line_number":6349,"context_line":"        ``sleep()``."},{"line_number":6350,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":3,"id":"bec10182_2464617e","line":6347,"range":{"start_line":6346,"start_character":39,"end_line":6347,"end_character":44},"updated":"2023-05-18 18:34:33.000000000","message":"This feels a little funny, getting a free `itertools.repeat(None)`... I think I\u0027d much prefer to have `next()` end with just a `return next(self.wrapped_iter)`.","commit_id":"975bf0e6677300485b33aca5471dcff75b0c2c71"}],"swift/proxy/controllers/base.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"3c46b732649b6a714854e67a711607ad1971f7a4","unresolved":true,"context_lines":[{"line_number":1252,"context_line":"                        if self.newest or self.server_type !\u003d \u0027Object\u0027:"},{"line_number":1253,"context_line":"                            raise"},{"line_number":1254,"context_line":"                        try:"},{"line_number":1255,"context_line":"                            self.fast_forward(self.bytes_used_from_backend)"},{"line_number":1256,"context_line":"                        except (HTTPException, ValueError):"},{"line_number":1257,"context_line":"                            six.reraise(exc_type, exc_value, exc_traceback)"},{"line_number":1258,"context_line":"                        except RangeAlreadyComplete:"}],"source_content_type":"text/x-python","patch_set":1,"id":"d47e5468_fd243db5","side":"PARENT","line":1255,"range":{"start_line":1255,"start_character":28,"end_line":1255,"end_character":45},"updated":"2023-05-17 12:37:01.000000000","message":"if fast_forward succeeds then AFAICT we go back to part_file.read without testing if nchunks %5 \u003d\u003d 0 \n\nIDK if that was intentional, or whether we should (in the new version) call sleeper.maybe_sleep() here too?","commit_id":"a0c5ac29a1e4f5dd5ee66ceb3d319774017cadfc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"46e29ac095f77787152dac83811e35107a31ca04","unresolved":false,"context_lines":[{"line_number":1252,"context_line":"                        if self.newest or self.server_type !\u003d \u0027Object\u0027:"},{"line_number":1253,"context_line":"                            raise"},{"line_number":1254,"context_line":"                        try:"},{"line_number":1255,"context_line":"                            self.fast_forward(self.bytes_used_from_backend)"},{"line_number":1256,"context_line":"                        except (HTTPException, ValueError):"},{"line_number":1257,"context_line":"                            six.reraise(exc_type, exc_value, exc_traceback)"},{"line_number":1258,"context_line":"                        except RangeAlreadyComplete:"}],"source_content_type":"text/x-python","patch_set":1,"id":"19b74556_995baa48","side":"PARENT","line":1255,"range":{"start_line":1255,"start_character":28,"end_line":1255,"end_character":45},"in_reply_to":"d47e5468_fd243db5","updated":"2023-05-18 15:44:45.000000000","message":"Done","commit_id":"a0c5ac29a1e4f5dd5ee66ceb3d319774017cadfc"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"8e15262fa9ce0903ff49e4984d3130ee2b431af1","unresolved":true,"context_lines":[{"line_number":1342,"context_line":"                                  if (end_byte is not None"},{"line_number":1343,"context_line":"                                      and start_byte is not None)"},{"line_number":1344,"context_line":"                                  else None)"},{"line_number":1345,"context_line":"                    part_iter \u003d iter_bytes_from_response_part(part, byte_count)"},{"line_number":1346,"context_line":"                    yield {\u0027start_byte\u0027: start_byte, \u0027end_byte\u0027: end_byte,"},{"line_number":1347,"context_line":"                           \u0027entity_length\u0027: length, \u0027headers\u0027: headers,"},{"line_number":1348,"context_line":"                           \u0027part_iter\u0027: part_iter}"}],"source_content_type":"text/x-python","patch_set":1,"id":"a6a381be_a33d08e1","line":1345,"updated":"2023-05-17 21:00:03.000000000","message":"```\npart_iter \u003d CooperativeIter(iter_bytes_from_response_part(part, byte_count),\n                            trampoline_every\u003d5)\n```\nfeels like a better interface (+/- the kwarg name).","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"46e29ac095f77787152dac83811e35107a31ca04","unresolved":false,"context_lines":[{"line_number":1342,"context_line":"                                  if (end_byte is not None"},{"line_number":1343,"context_line":"                                      and start_byte is not None)"},{"line_number":1344,"context_line":"                                  else None)"},{"line_number":1345,"context_line":"                    part_iter \u003d iter_bytes_from_response_part(part, byte_count)"},{"line_number":1346,"context_line":"                    yield {\u0027start_byte\u0027: start_byte, \u0027end_byte\u0027: end_byte,"},{"line_number":1347,"context_line":"                           \u0027entity_length\u0027: length, \u0027headers\u0027: headers,"},{"line_number":1348,"context_line":"                           \u0027part_iter\u0027: part_iter}"}],"source_content_type":"text/x-python","patch_set":1,"id":"bbe68a96_ce569936","line":1345,"in_reply_to":"a6a381be_a33d08e1","updated":"2023-05-18 15:44:45.000000000","message":"Done","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"be7a0a8662502fa55787d85e16269e4df184fd39","unresolved":true,"context_lines":[{"line_number":1339,"context_line":"                                      and start_byte is not None)"},{"line_number":1340,"context_line":"                                  else None)"},{"line_number":1341,"context_line":"                    part_iter \u003d CooperativeIterator("},{"line_number":1342,"context_line":"                        iter_bytes_from_response_part(part, byte_count))"},{"line_number":1343,"context_line":"                    yield {\u0027start_byte\u0027: start_byte, \u0027end_byte\u0027: end_byte,"},{"line_number":1344,"context_line":"                           \u0027entity_length\u0027: length, \u0027headers\u0027: headers,"},{"line_number":1345,"context_line":"                           \u0027part_iter\u0027: part_iter}"}],"source_content_type":"text/x-python","patch_set":2,"id":"64da9102_0b64242a","line":1342,"updated":"2023-05-18 18:11:41.000000000","message":"subtle change here: we\u0027ll now sleep on every 1 in 5 chunks yielded towards the client, rather than 1 in 5 chunks read from the backend. By default the two have the same size, so it should work about the same. Besides, to woute the original code \"The number 5 here was chosen by making stuff up.\"","commit_id":"3a7a8bd2173673176406d6c04c2503fa67b4c970"}],"swift/proxy/controllers/obj.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"8e15262fa9ce0903ff49e4984d3130ee2b431af1","unresolved":true,"context_lines":[{"line_number":2739,"context_line":"                if not chunk:"},{"line_number":2740,"context_line":"                    break"},{"line_number":2741,"context_line":""},{"line_number":2742,"context_line":"                sleeper.maybe_sleep()"},{"line_number":2743,"context_line":""},{"line_number":2744,"context_line":"    def _get_response_parts_iter(self, req):"},{"line_number":2745,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"4019024c_0f4395f9","line":2742,"updated":"2023-05-17 21:00:03.000000000","message":"How much does it actually matter whether we might sleep as part of the incr vs here? Is this something just to appease tests? Similar question over in base.py","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"46e29ac095f77787152dac83811e35107a31ca04","unresolved":true,"context_lines":[{"line_number":2739,"context_line":"                if not chunk:"},{"line_number":2740,"context_line":"                    break"},{"line_number":2741,"context_line":""},{"line_number":2742,"context_line":"                sleeper.maybe_sleep()"},{"line_number":2743,"context_line":""},{"line_number":2744,"context_line":"    def _get_response_parts_iter(self, req):"},{"line_number":2745,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"e4919d7c_019c9d9a","line":2742,"in_reply_to":"4019024c_0f4395f9","updated":"2023-05-18 15:44:45.000000000","message":"The question I was asking myself is how much does it matter if we don\u0027t increment in the except clause, and just increment+sleep here every time a chunk is handled?","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"be7a0a8662502fa55787d85e16269e4df184fd39","unresolved":false,"context_lines":[{"line_number":2739,"context_line":"                if not chunk:"},{"line_number":2740,"context_line":"                    break"},{"line_number":2741,"context_line":""},{"line_number":2742,"context_line":"                sleeper.maybe_sleep()"},{"line_number":2743,"context_line":""},{"line_number":2744,"context_line":"    def _get_response_parts_iter(self, req):"},{"line_number":2745,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"f1f35159_f7debacb","line":2742,"in_reply_to":"46d22e6a_8e90a2b4","updated":"2023-05-18 18:11:41.000000000","message":"Ack","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":597,"name":"Pete Zaitcev","email":"zaitcev@kotori.zaitcev.us","username":"zaitcev"},"change_message_id":"e32433ac79efc201b58960d93318163670d91fe7","unresolved":true,"context_lines":[{"line_number":2739,"context_line":"                if not chunk:"},{"line_number":2740,"context_line":"                    break"},{"line_number":2741,"context_line":""},{"line_number":2742,"context_line":"                sleeper.maybe_sleep()"},{"line_number":2743,"context_line":""},{"line_number":2744,"context_line":"    def _get_response_parts_iter(self, req):"},{"line_number":2745,"context_line":"        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"46d22e6a_8e90a2b4","line":2742,"in_reply_to":"e4919d7c_019c9d9a","updated":"2023-05-18 17:04:56.000000000","message":"I\u0027m pretty sure there ought to be chances to schedule away while we\u0027re selecting new source and opening a connection to it.","commit_id":"7ab509811c93558220791588822ae0b345918265"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"be7a0a8662502fa55787d85e16269e4df184fd39","unresolved":true,"context_lines":[{"line_number":2767,"context_line":"                                      and start_byte is not None)"},{"line_number":2768,"context_line":"                                  else None)"},{"line_number":2769,"context_line":"                    part_iter \u003d CooperativeIterator("},{"line_number":2770,"context_line":"                        self.iter_bytes_from_response_part(part, byte_count))"},{"line_number":2771,"context_line":"                    yield {\u0027start_byte\u0027: start_byte, \u0027end_byte\u0027: end_byte,"},{"line_number":2772,"context_line":"                           \u0027entity_length\u0027: length, \u0027headers\u0027: headers,"},{"line_number":2773,"context_line":"                           \u0027part_iter\u0027: part_iter}"}],"source_content_type":"text/x-python","patch_set":2,"id":"83c5c877_717ca913","line":2770,"updated":"2023-05-18 18:11:41.000000000","message":"same subtle change as in base.py w.r.t now sleeping on 1 in 5 *yielded* chunks","commit_id":"3a7a8bd2173673176406d6c04c2503fa67b4c970"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"be7a0a8662502fa55787d85e16269e4df184fd39","unresolved":true,"context_lines":[{"line_number":3357,"context_line":"                    raise HTTPRequestEntityTooLarge(request\u003dreq)"},{"line_number":3358,"context_line":""},{"line_number":3359,"context_line":"                send_chunk(chunk)"},{"line_number":3360,"context_line":"                coop_iter.next()"},{"line_number":3361,"context_line":""},{"line_number":3362,"context_line":"            ml \u003d req.message_length()"},{"line_number":3363,"context_line":"            if ml and bytes_transferred \u003c ml:"}],"source_content_type":"text/x-python","patch_set":2,"id":"cc2f93bb_7058248c","line":3360,"updated":"2023-05-18 18:11:41.000000000","message":"obvious follow up might be to refactor the while loop to an iterator and wrap it, but I\u0027m not sure I have the appetite for that yet - I want to ship a fix! \n\nFor now, the CooperativeIterator will just act as a sleep injector.","commit_id":"3a7a8bd2173673176406d6c04c2503fa67b4c970"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"54d61832474c0914196a6d222d00e25ee6513ec8","unresolved":true,"context_lines":[{"line_number":1030,"context_line":"                                     self.app.client_timeout,"},{"line_number":1031,"context_line":"                                     ChunkReadTimeout):"},{"line_number":1032,"context_line":"                    try:"},{"line_number":1033,"context_line":"                        chunk \u003d next(data_source)"},{"line_number":1034,"context_line":"                    except StopIteration:"},{"line_number":1035,"context_line":"                        break"},{"line_number":1036,"context_line":"                bytes_transferred +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":3,"id":"d8f7838d_f2f41b65","line":1033,"range":{"start_line":1033,"start_character":32,"end_line":1033,"end_character":49},"updated":"2023-05-18 18:34:33.000000000","message":"Would it work for us to do something like\n```\ndata_source \u003d CooperativeIter(data_source)\n```\nas we come into `_transfer_data`?","commit_id":"975bf0e6677300485b33aca5471dcff75b0c2c71"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6fa369346c39f38e0e4f970eef3be9e2c2fd67e0","unresolved":true,"context_lines":[{"line_number":1030,"context_line":"                                     self.app.client_timeout,"},{"line_number":1031,"context_line":"                                     ChunkReadTimeout):"},{"line_number":1032,"context_line":"                    try:"},{"line_number":1033,"context_line":"                        chunk \u003d next(data_source)"},{"line_number":1034,"context_line":"                    except StopIteration:"},{"line_number":1035,"context_line":"                        break"},{"line_number":1036,"context_line":"                bytes_transferred +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":3,"id":"e08dd3a1_59a68820","line":1033,"range":{"start_line":1033,"start_character":32,"end_line":1033,"end_character":49},"in_reply_to":"82ff50d8_fec76f86","updated":"2023-05-19 09:02:43.000000000","message":"duh! of course.\n\nend of a long day...I\u0027m thinking \"extracting this while loop is going to be a chore\", Tim comes along...one line change 👌 Many hands make light work I guess. Thanks Tim!","commit_id":"975bf0e6677300485b33aca5471dcff75b0c2c71"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"616b638a3eebbf68198f6e32b8d9f765f95b7ff3","unresolved":true,"context_lines":[{"line_number":1030,"context_line":"                                     self.app.client_timeout,"},{"line_number":1031,"context_line":"                                     ChunkReadTimeout):"},{"line_number":1032,"context_line":"                    try:"},{"line_number":1033,"context_line":"                        chunk \u003d next(data_source)"},{"line_number":1034,"context_line":"                    except StopIteration:"},{"line_number":1035,"context_line":"                        break"},{"line_number":1036,"context_line":"                bytes_transferred +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":3,"id":"82ff50d8_fec76f86","line":1033,"range":{"start_line":1033,"start_character":32,"end_line":1033,"end_character":49},"in_reply_to":"d8f7838d_f2f41b65","updated":"2023-05-18 18:52:51.000000000","message":"that would be nice if that worked!  the unwapped/itertools.repeat(None) usage of CooperativeIter was surprising/confusing to me.","commit_id":"975bf0e6677300485b33aca5471dcff75b0c2c71"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"54d61832474c0914196a6d222d00e25ee6513ec8","unresolved":true,"context_lines":[{"line_number":3349,"context_line":"                                     self.app.client_timeout,"},{"line_number":3350,"context_line":"                                     ChunkReadTimeout):"},{"line_number":3351,"context_line":"                    try:"},{"line_number":3352,"context_line":"                        chunk \u003d next(data_source)"},{"line_number":3353,"context_line":"                    except StopIteration:"},{"line_number":3354,"context_line":"                        break"},{"line_number":3355,"context_line":"                bytes_transferred +\u003d len(chunk)"}],"source_content_type":"text/x-python","patch_set":3,"id":"60e035a1_ef609adf","line":3352,"range":{"start_line":3352,"start_character":32,"end_line":3352,"end_character":49},"updated":"2023-05-18 18:34:33.000000000","message":"ditto","commit_id":"975bf0e6677300485b33aca5471dcff75b0c2c71"}]}
