)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5d15bea0a34c79fe353276a566db824d5426b0bc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"35904139_c01802f4","updated":"2022-04-13 10:09:15.000000000","message":"this will be a useful optimisation","commit_id":"f0fa3b607aed385185526e506cf9eb95288fe871"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"7622ea9888ba74772e61ed34fc84a43727b05c5d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"d8826258_3f907f38","updated":"2022-04-13 21:41:55.000000000","message":"I think we need more tests to feel confident about the optimization for reverse listings.\n\nI\u0027d be ok shipping something simpler until we can get more tests, e.g.\n\nif not reverse and shard_range.upper.startswith(marker):\n    continue\n\nThanks for kicking up something so quickly!","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"28778f1f17f951b754448537598c186f18471791","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"22c273dd_50602315","updated":"2022-07-20 10:01:32.000000000","message":"I had a play with a non-reverse test, and having the `shard_range.upper !\u003d last_name` didn\u0027t seem to make a difference. But that could just be because I don\u0027t understand the reason for it, so maybe didn\u0027t set up the test correct.","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9bd279b154bdc054e87e90ebadf4a96803d9951b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"c61badf4_9b50cef5","updated":"2022-06-15 00:24:27.000000000","message":"this looks pretty good!","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"30284b2234721f8fb92a0ddcb67f1f2993439826","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"322959df_b92aeb0c","updated":"2022-07-07 19:08:10.000000000","message":"this seems to be working correctly in prod at least for un-reversed listings.\n\nI don\u0027t care enough about getting better tests for this change to write them myself, so we maybe we can merge this as is.","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"35728341878e5421271c7ab7c2dc30fc9219790b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"bd4faf34_09d01597","updated":"2022-07-25 07:27:42.000000000","message":"Hm, this new approach seems much easier to understand and read. I\u0027ll have a bit of a play with it.","commit_id":"25463b253f8d5dd021042a4b2fa7c4f1d359ae80"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"4f802da3353a9e58bf9dfc44b1db14feb32e60c0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"46db792e_e69133f6","updated":"2022-08-03 07:04:52.000000000","message":"Yup, I like this approach much more. At least for me it\u0027s much easier to read and understand. Nice one Tim.","commit_id":"25463b253f8d5dd021042a4b2fa7c4f1d359ae80"}],"swift/proxy/controllers/container.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"aa48d181cd80f14078a314a8592d7a63d4b2a528","unresolved":true,"context_lines":[{"line_number":445,"context_line":"                    if next_possible_name \u003c shard_range:"},{"line_number":446,"context_line":"                        continue"},{"line_number":447,"context_line":"                else:"},{"line_number":448,"context_line":"                    if not params[\u0027marker\u0027].endswith(\u0027\\xff\u0027):"},{"line_number":449,"context_line":"                        next_possible_name \u003d params[\u0027marker\u0027][:-1] + chr("},{"line_number":450,"context_line":"                            ord(params[\u0027marker\u0027][-1]) + 1)"},{"line_number":451,"context_line":"                        if next_possible_name \u003e shard_range:"}],"source_content_type":"text/x-python","patch_set":1,"id":"6a6932ee_4009ca35","line":448,"updated":"2022-04-12 16:53:59.000000000","message":"This \u0027\\xff\u0027 is a definite smell. Good indication that `next_possible_name \u003e shard_range` isn\u0027t a valid comparison (wsgi vs native strings).","commit_id":"f0fa3b607aed385185526e506cf9eb95288fe871"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0600184f49843472a610c54e8fc36c0c7866ecfa","unresolved":false,"context_lines":[{"line_number":445,"context_line":"                    if next_possible_name \u003c shard_range:"},{"line_number":446,"context_line":"                        continue"},{"line_number":447,"context_line":"                else:"},{"line_number":448,"context_line":"                    if not params[\u0027marker\u0027].endswith(\u0027\\xff\u0027):"},{"line_number":449,"context_line":"                        next_possible_name \u003d params[\u0027marker\u0027][:-1] + chr("},{"line_number":450,"context_line":"                            ord(params[\u0027marker\u0027][-1]) + 1)"},{"line_number":451,"context_line":"                        if next_possible_name \u003e shard_range:"}],"source_content_type":"text/x-python","patch_set":1,"id":"14f18a10_098548a9","line":448,"in_reply_to":"6a6932ee_4009ca35","updated":"2022-06-09 21:39:24.000000000","message":"Done","commit_id":"f0fa3b607aed385185526e506cf9eb95288fe871"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"b8c919006c8ba82484b19bacb82afabe3925570b","unresolved":true,"context_lines":[{"line_number":447,"context_line":"                else:"},{"line_number":448,"context_line":"                    if not params[\u0027marker\u0027].endswith(\u0027\\xff\u0027):"},{"line_number":449,"context_line":"                        next_possible_name \u003d params[\u0027marker\u0027][:-1] + chr("},{"line_number":450,"context_line":"                            ord(params[\u0027marker\u0027][-1]) + 1)"},{"line_number":451,"context_line":"                        if next_possible_name \u003e shard_range:"},{"line_number":452,"context_line":"                            continue"},{"line_number":453,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"104f8ceb_179f832d","line":450,"updated":"2022-04-12 06:08:28.000000000","message":"Because we\u0027re dealing with delimiters here and the marker ends in a delimiter. Should this rather be marker + \u0027\\x00\u0027, becuase the rest of the psudo filesystem could under the current marker could span more then a shard? Ie:\n\n  $ curl -X GET \u003cblah\u003e/v1/a/c?prefix\u003dphotos/\u0026marker\u003dphotos/\u0026delimiter\u003d/\n  photos/animals/     \u003c- shard 1\n  photos/people/      \u003c- shard 2\n  photos/plants/      \u003c- shard 3\n\nIn this case, the next_possible_name would become photos0, so would skip the first 2 shards and only talk to shard 3, assuming it contains the namespace to the end.","commit_id":"f0fa3b607aed385185526e506cf9eb95288fe871"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"aa48d181cd80f14078a314a8592d7a63d4b2a528","unresolved":true,"context_lines":[{"line_number":447,"context_line":"                else:"},{"line_number":448,"context_line":"                    if not params[\u0027marker\u0027].endswith(\u0027\\xff\u0027):"},{"line_number":449,"context_line":"                        next_possible_name \u003d params[\u0027marker\u0027][:-1] + chr("},{"line_number":450,"context_line":"                            ord(params[\u0027marker\u0027][-1]) + 1)"},{"line_number":451,"context_line":"                        if next_possible_name \u003e shard_range:"},{"line_number":452,"context_line":"                            continue"},{"line_number":453,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"c30b24c9_ba57ef2d","line":450,"in_reply_to":"104f8ceb_179f832d","updated":"2022-04-12 16:53:59.000000000","message":"No, that\u0027s the optimization -- (marker + \u0027\\x00\u0027) all the way through (marker + \u0027\\xff\u0027 * BIGNUM) are all going to be contained \"within\" that marker entry that we already found from the previous shard range.\n\nIf we\u0027ve got no prefix and some shards like\n\n \u0027\u0027 through \u0027foo/bar\u0027\n \u0027foo/bar\u0027 through \u0027foo/baz\u0027\n \u0027foo/baz\u0027 through \u0027\u0027\n\nthen once we get back \u0027foo/\u0027 from the first shard, there\u0027s no reason to query the second shard at all; \u0027foo/\u0027 is the only result we could hope to get from it. So, skip it and go straight to the third shard.\n\nI\u0027ll write up some tests to demonstrate it.","commit_id":"f0fa3b607aed385185526e506cf9eb95288fe871"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"56aa74babb9a825f5243145d7b45c39fa2468e90","unresolved":true,"context_lines":[{"line_number":447,"context_line":"                else:"},{"line_number":448,"context_line":"                    if not params[\u0027marker\u0027].endswith(\u0027\\xff\u0027):"},{"line_number":449,"context_line":"                        next_possible_name \u003d params[\u0027marker\u0027][:-1] + chr("},{"line_number":450,"context_line":"                            ord(params[\u0027marker\u0027][-1]) + 1)"},{"line_number":451,"context_line":"                        if next_possible_name \u003e shard_range:"},{"line_number":452,"context_line":"                            continue"},{"line_number":453,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"24666914_383ddf23","line":450,"in_reply_to":"c30b24c9_ba57ef2d","updated":"2022-04-12 23:17:34.000000000","message":"oh, because we\u0027re not querying to get the objects, we\u0027re just expecting a subdir/ because of the delimiter.. OK I think I got it. Turns out I just needed to see this with fresh eyes!\n\nThat makes _SO_ much more sense now! Yeah, needs some tests, that would make it much more clear. Damn psudo directories, always confuses me.","commit_id":"f0fa3b607aed385185526e506cf9eb95288fe871"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"5d15bea0a34c79fe353276a566db824d5426b0bc","unresolved":true,"context_lines":[{"line_number":449,"context_line":"                        next_possible_name \u003d params[\u0027marker\u0027][:-1] + chr("},{"line_number":450,"context_line":"                            ord(params[\u0027marker\u0027][-1]) + 1)"},{"line_number":451,"context_line":"                        if next_possible_name \u003e shard_range:"},{"line_number":452,"context_line":"                            continue"},{"line_number":453,"context_line":""},{"line_number":454,"context_line":"            self.logger.debug("},{"line_number":455,"context_line":"                \u0027Getting listing part %d from shard %s %s with %s\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"8009eb60_9790ee77","line":452,"updated":"2022-04-13 10:09:15.000000000","message":"is it possible to use the simpler condition of:\n\n  if shard_range.upper.startswith(`params[\u0027marker\u0027]`):\n      continue","commit_id":"f0fa3b607aed385185526e506cf9eb95288fe871"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0600184f49843472a610c54e8fc36c0c7866ecfa","unresolved":false,"context_lines":[{"line_number":449,"context_line":"                        next_possible_name \u003d params[\u0027marker\u0027][:-1] + chr("},{"line_number":450,"context_line":"                            ord(params[\u0027marker\u0027][-1]) + 1)"},{"line_number":451,"context_line":"                        if next_possible_name \u003e shard_range:"},{"line_number":452,"context_line":"                            continue"},{"line_number":453,"context_line":""},{"line_number":454,"context_line":"            self.logger.debug("},{"line_number":455,"context_line":"                \u0027Getting listing part %d from shard %s %s with %s\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"4596562e_1b01d231","line":452,"in_reply_to":"30aecbb0_c68f4f6e","updated":"2022-06-09 21:39:24.000000000","message":"Done","commit_id":"f0fa3b607aed385185526e506cf9eb95288fe871"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"7622ea9888ba74772e61ed34fc84a43727b05c5d","unresolved":true,"context_lines":[{"line_number":449,"context_line":"                        next_possible_name \u003d params[\u0027marker\u0027][:-1] + chr("},{"line_number":450,"context_line":"                            ord(params[\u0027marker\u0027][-1]) + 1)"},{"line_number":451,"context_line":"                        if next_possible_name \u003e shard_range:"},{"line_number":452,"context_line":"                            continue"},{"line_number":453,"context_line":""},{"line_number":454,"context_line":"            self.logger.debug("},{"line_number":455,"context_line":"                \u0027Getting listing part %d from shard %s %s with %s\u0027,"}],"source_content_type":"text/x-python","patch_set":1,"id":"30aecbb0_c68f4f6e","line":452,"in_reply_to":"8009eb60_9790ee77","updated":"2022-04-13 21:41:55.000000000","message":"AttributeError: \u0027MaxBound\u0027 object has no attribute \u0027startswith\u0027\n\nbut...\n\n\tdiff --git a/swift/proxy/controllers/container.py b/swift/proxy/controllers/container.py\n\tindex 728583778..fa93bb3ec 100644\n\t--- a/swift/proxy/controllers/container.py\n\t+++ b/swift/proxy/controllers/container.py\n\t@@ -448,14 +448,8 @@ class ContainerController(Controller):\n\t\t\t     if next_possible_name \u003c shard_range:\n\t\t\t\t continue\n\t\t\t else:\n\t-                    try:\n\t-                        next_possible_name \u003d last_name[:-1] + chr(\n\t-                            ord(last_name[-1]) + 1)\n\t-                    except ValueError:\n\t-                        pass\n\t-                    else:\n\t-                        if next_possible_name \u003e shard_range:\n\t-                            continue\n\t+                    if str(shard_range.upper).startswith(params[\u0027marker\u0027]):\n\t+                        continue\n\t \n\t\t     self.logger.debug(\n\t\t\t \u0027Getting listing part %d from shard %s %s with %s\u0027,\n\n\n\n... seems to pass the one test we have!","commit_id":"f0fa3b607aed385185526e506cf9eb95288fe871"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"7622ea9888ba74772e61ed34fc84a43727b05c5d","unresolved":true,"context_lines":[{"line_number":437,"context_line":"                    if just_past \u003c shard_range:"},{"line_number":438,"context_line":"                        continue"},{"line_number":439,"context_line":""},{"line_number":440,"context_line":"            if delimiter and last_name.endswith(params[\u0027delimiter\u0027]):"},{"line_number":441,"context_line":"                if reverse:"},{"line_number":442,"context_line":"                    if last_name.endswith(\u0027\\x00\u0027):"},{"line_number":443,"context_line":"                        next_possible_name \u003d last_name[:-1]"}],"source_content_type":"text/x-python","patch_set":2,"id":"57ff0c31_c7194832","line":440,"updated":"2022-04-13 21:41:55.000000000","message":"\u0027\u0027.endswith(\u0027\u0027) \u003d\u003d True\n\nDo we want to be in here during the default case?","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4208d5fdf8d5df06d6e0c5ab81d52b051212e17d","unresolved":true,"context_lines":[{"line_number":437,"context_line":"                    if just_past \u003c shard_range:"},{"line_number":438,"context_line":"                        continue"},{"line_number":439,"context_line":""},{"line_number":440,"context_line":"            if delimiter and last_name.endswith(params[\u0027delimiter\u0027]):"},{"line_number":441,"context_line":"                if reverse:"},{"line_number":442,"context_line":"                    if last_name.endswith(\u0027\\x00\u0027):"},{"line_number":443,"context_line":"                        next_possible_name \u003d last_name[:-1]"}],"source_content_type":"text/x-python","patch_set":2,"id":"922f4fba_0e4d7106","line":440,"in_reply_to":"57ff0c31_c7194832","updated":"2022-04-13 22:00:18.000000000","message":"Hence the \"delimiter and\"\n\nThis should be using delimiter, though, instead of params[\u0027delimiter\u0027] -- stupid WSGI strings...","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0600184f49843472a610c54e8fc36c0c7866ecfa","unresolved":false,"context_lines":[{"line_number":437,"context_line":"                    if just_past \u003c shard_range:"},{"line_number":438,"context_line":"                        continue"},{"line_number":439,"context_line":""},{"line_number":440,"context_line":"            if delimiter and last_name.endswith(params[\u0027delimiter\u0027]):"},{"line_number":441,"context_line":"                if reverse:"},{"line_number":442,"context_line":"                    if last_name.endswith(\u0027\\x00\u0027):"},{"line_number":443,"context_line":"                        next_possible_name \u003d last_name[:-1]"}],"source_content_type":"text/x-python","patch_set":2,"id":"aaa04bd9_32f483c3","line":440,"in_reply_to":"922f4fba_0e4d7106","updated":"2022-06-09 21:39:24.000000000","message":"Done","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"7622ea9888ba74772e61ed34fc84a43727b05c5d","unresolved":true,"context_lines":[{"line_number":438,"context_line":"                        continue"},{"line_number":439,"context_line":""},{"line_number":440,"context_line":"            if delimiter and last_name.endswith(params[\u0027delimiter\u0027]):"},{"line_number":441,"context_line":"                if reverse:"},{"line_number":442,"context_line":"                    if last_name.endswith(\u0027\\x00\u0027):"},{"line_number":443,"context_line":"                        next_possible_name \u003d last_name[:-1]"},{"line_number":444,"context_line":"                    else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"ca12a1b0_677adb65","line":441,"updated":"2022-04-13 21:41:55.000000000","message":"I don\u0027t think this brach is tested at all?","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0600184f49843472a610c54e8fc36c0c7866ecfa","unresolved":false,"context_lines":[{"line_number":438,"context_line":"                        continue"},{"line_number":439,"context_line":""},{"line_number":440,"context_line":"            if delimiter and last_name.endswith(params[\u0027delimiter\u0027]):"},{"line_number":441,"context_line":"                if reverse:"},{"line_number":442,"context_line":"                    if last_name.endswith(\u0027\\x00\u0027):"},{"line_number":443,"context_line":"                        next_possible_name \u003d last_name[:-1]"},{"line_number":444,"context_line":"                    else:"}],"source_content_type":"text/x-python","patch_set":2,"id":"33a9d1d6_82f4237e","line":441,"in_reply_to":"ca12a1b0_677adb65","updated":"2022-06-09 21:39:24.000000000","message":"Done","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"7622ea9888ba74772e61ed34fc84a43727b05c5d","unresolved":true,"context_lines":[{"line_number":440,"context_line":"            if delimiter and last_name.endswith(params[\u0027delimiter\u0027]):"},{"line_number":441,"context_line":"                if reverse:"},{"line_number":442,"context_line":"                    if last_name.endswith(\u0027\\x00\u0027):"},{"line_number":443,"context_line":"                        next_possible_name \u003d last_name[:-1]"},{"line_number":444,"context_line":"                    else:"},{"line_number":445,"context_line":"                        next_possible_name \u003d last_name[:-1] + chr("},{"line_number":446,"context_line":"                            ord(last_name[-1]) - 1)"}],"source_content_type":"text/x-python","patch_set":2,"id":"6eded31f_cea0c937","line":443,"updated":"2022-04-13 21:41:55.000000000","message":"right so, you can\u0027t have anything lower in the last pos than null - but you could have a shorter string","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"7622ea9888ba74772e61ed34fc84a43727b05c5d","unresolved":true,"context_lines":[{"line_number":443,"context_line":"                        next_possible_name \u003d last_name[:-1]"},{"line_number":444,"context_line":"                    else:"},{"line_number":445,"context_line":"                        next_possible_name \u003d last_name[:-1] + chr("},{"line_number":446,"context_line":"                            ord(last_name[-1]) - 1)"},{"line_number":447,"context_line":""},{"line_number":448,"context_line":"                    if next_possible_name \u003c shard_range:"},{"line_number":449,"context_line":"                        continue"}],"source_content_type":"text/x-python","patch_set":2,"id":"26a0fa8d_07cf870f","line":446,"updated":"2022-04-13 21:41:55.000000000","message":"so there could be a name between next_possible_name and last_name - but it would for sure *startswith* next_possible_name which might be correct for reverse listsings?","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4208d5fdf8d5df06d6e0c5ab81d52b051212e17d","unresolved":true,"context_lines":[{"line_number":443,"context_line":"                        next_possible_name \u003d last_name[:-1]"},{"line_number":444,"context_line":"                    else:"},{"line_number":445,"context_line":"                        next_possible_name \u003d last_name[:-1] + chr("},{"line_number":446,"context_line":"                            ord(last_name[-1]) - 1)"},{"line_number":447,"context_line":""},{"line_number":448,"context_line":"                    if next_possible_name \u003c shard_range:"},{"line_number":449,"context_line":"                        continue"}],"source_content_type":"text/x-python","patch_set":2,"id":"f2b2bdfd_cb875a44","line":446,"in_reply_to":"26a0fa8d_07cf870f","updated":"2022-04-13 22:00:18.000000000","message":":-/ Yeah, this feels off. I kind of *want* to tack on a b\u0027\\xff\u0027 or something, but that\u0027d only work if we\u0027re dealing in bytes..","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0600184f49843472a610c54e8fc36c0c7866ecfa","unresolved":false,"context_lines":[{"line_number":443,"context_line":"                        next_possible_name \u003d last_name[:-1]"},{"line_number":444,"context_line":"                    else:"},{"line_number":445,"context_line":"                        next_possible_name \u003d last_name[:-1] + chr("},{"line_number":446,"context_line":"                            ord(last_name[-1]) - 1)"},{"line_number":447,"context_line":""},{"line_number":448,"context_line":"                    if next_possible_name \u003c shard_range:"},{"line_number":449,"context_line":"                        continue"}],"source_content_type":"text/x-python","patch_set":2,"id":"702ec24d_c9d6fea1","line":446,"in_reply_to":"f2b2bdfd_cb875a44","updated":"2022-06-09 21:39:24.000000000","message":"Ack","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4208d5fdf8d5df06d6e0c5ab81d52b051212e17d","unresolved":true,"context_lines":[{"line_number":452,"context_line":"                        next_possible_name \u003d last_name[:-1] + chr("},{"line_number":453,"context_line":"                            ord(last_name[-1]) + 1)"},{"line_number":454,"context_line":"                    except ValueError:"},{"line_number":455,"context_line":"                        pass"},{"line_number":456,"context_line":"                    else:"},{"line_number":457,"context_line":"                        if next_possible_name \u003e shard_range:"},{"line_number":458,"context_line":"                            continue"}],"source_content_type":"text/x-python","patch_set":2,"id":"1d525138_cad13e68","line":455,"updated":"2022-04-13 22:00:18.000000000","message":"Maybe there\u0027s more I could do here...\n\nOTOH, at least it\u0027s not blowing up! https://bugs.launchpad.net/swift/+bug/1968923","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"0600184f49843472a610c54e8fc36c0c7866ecfa","unresolved":false,"context_lines":[{"line_number":452,"context_line":"                        next_possible_name \u003d last_name[:-1] + chr("},{"line_number":453,"context_line":"                            ord(last_name[-1]) + 1)"},{"line_number":454,"context_line":"                    except ValueError:"},{"line_number":455,"context_line":"                        pass"},{"line_number":456,"context_line":"                    else:"},{"line_number":457,"context_line":"                        if next_possible_name \u003e shard_range:"},{"line_number":458,"context_line":"                            continue"}],"source_content_type":"text/x-python","patch_set":2,"id":"125734f3_7e999d71","line":455,"in_reply_to":"1d525138_cad13e68","updated":"2022-06-09 21:39:24.000000000","message":"Ack","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"da41b144a5cbfc1891485a43f809d00d26091321","unresolved":true,"context_lines":[{"line_number":437,"context_line":"                    if just_past \u003c shard_range:"},{"line_number":438,"context_line":"                        continue"},{"line_number":439,"context_line":""},{"line_number":440,"context_line":"            if delimiter and last_name.endswith(delimiter):"},{"line_number":441,"context_line":"                if reverse:"},{"line_number":442,"context_line":"                    if str(shard_range.lower).startswith(last_name):"},{"line_number":443,"context_line":"                        continue"}],"source_content_type":"text/x-python","patch_set":4,"id":"aa1f3934_42388d9b","line":440,"updated":"2022-07-20 17:03:04.000000000","message":"This isn\u0027t sufficient -- we need to consider prefix. Or rather, we need to track whether last_name was an object entry or a subdir entry.\n\nIn particular, try making a container with some (pathologically named) objects:\n\n x/\n x//\n x///\n x////\n\nand shards that only have one object, so ranges like:\n\n \u0027\u0027     - \u0027x/\u0027\n \u0027x/\u0027   - \u0027x//\u0027\n \u0027x//\u0027  - \u0027x///\u0027\n \u0027x///\u0027 - \u0027\u0027\n\nDo a query like `?delimiter\u003d//\u0026prefix\u003dx//` -- we\u0027ll\n\n* skip the first shard, since it can\u0027t contain the prefix\n* find an object record for \u0027x//\u0027 from the second shard (but here we assume it was a subdir!)\n* skip the third shard since \u0027x///\u0027 starts with our last_name, \u0027x//\u0027\n* find a subdir entry \u0027x////\u0027 from the last shard\n\ncausing us to miss \u0027x///\u0027.\n\n---\n\nOh! Even simpler repro; no multi-character delimiter required: given a listing like\n\n x/\n x/y/z\n y\n\nand shard ranges like\n\n \u0027\u0027      - \u0027x/\u0027\n \u0027x/\u0027    - \u0027x/y/z\u0027\n \u0027x/y/z\u0027 - \u0027\u0027\n\nthen `?delimiter\u003d/\u0026prefix\u003dx/` will miss the \u0027x/y/\u0027 subdir.","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9bd279b154bdc054e87e90ebadf4a96803d9951b","unresolved":true,"context_lines":[{"line_number":443,"context_line":"                        continue"},{"line_number":444,"context_line":"                else:"},{"line_number":445,"context_line":"                    if str(shard_range.upper).startswith(last_name) and \\"},{"line_number":446,"context_line":"                            shard_range.upper !\u003d last_name:"},{"line_number":447,"context_line":"                        continue"},{"line_number":448,"context_line":""},{"line_number":449,"context_line":"            self.logger.debug("}],"source_content_type":"text/x-python","patch_set":4,"id":"87bad6eb_e6cf6975","line":446,"updated":"2022-06-15 00:24:27.000000000","message":"I don\u0027t think our tests hit the case where shard_range.upper \u003d\u003d last_name","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"},{"author":{"_account_id":7233,"name":"Matthew Oliver","email":"matt@oliver.net.au","username":"mattoliverau"},"change_message_id":"28778f1f17f951b754448537598c186f18471791","unresolved":true,"context_lines":[{"line_number":443,"context_line":"                        continue"},{"line_number":444,"context_line":"                else:"},{"line_number":445,"context_line":"                    if str(shard_range.upper).startswith(last_name) and \\"},{"line_number":446,"context_line":"                            shard_range.upper !\u003d last_name:"},{"line_number":447,"context_line":"                        continue"},{"line_number":448,"context_line":""},{"line_number":449,"context_line":"            self.logger.debug("}],"source_content_type":"text/x-python","patch_set":4,"id":"a3617d41_e89fac73","line":446,"range":{"start_line":446,"start_character":28,"end_line":446,"end_character":58},"updated":"2022-07-20 10:01:32.000000000","message":"I\u0027m trying to come to terms with this check.. last_name is the name of the last object and has to end with a delimiter. But by here we are in the next shard (not in reverse order). So by definition wont the upper always be bigger then the last object in the last shardrange.\n\nFurther, because it ends in delimiter we can assume it\u0027s a subdir.. but that means that there was an object (most likely) that is bigger then the last object (because it\u0027s a subdir, ie if the subdir is foo/ then in the shard before there must\u0027ve been a foo/\u003cplus_something\u003e. So how could the next range .upper be foo/? foo is smaller then foo/\u003cplus_something\u003e.\n\nIf it\u0027s just to be sure we\u0027re matching the last object which is included, I beleave we do an upper + \\x00 check to make sure we include it don\u0027t we?\n\nEverytime I come to subdir and pseudo folders, I always miss something obvious, just can\u0027t get the damn thing in my head. What am I missing?","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"da41b144a5cbfc1891485a43f809d00d26091321","unresolved":true,"context_lines":[{"line_number":443,"context_line":"                        continue"},{"line_number":444,"context_line":"                else:"},{"line_number":445,"context_line":"                    if str(shard_range.upper).startswith(last_name) and \\"},{"line_number":446,"context_line":"                            shard_range.upper !\u003d last_name:"},{"line_number":447,"context_line":"                        continue"},{"line_number":448,"context_line":""},{"line_number":449,"context_line":"            self.logger.debug("}],"source_content_type":"text/x-python","patch_set":4,"id":"98d00693_c15a9002","line":446,"range":{"start_line":446,"start_character":28,"end_line":446,"end_character":58},"in_reply_to":"a3617d41_e89fac73","updated":"2022-07-20 17:03:04.000000000","message":"Mostly, this was because I couldn\u0027t remember how delimiter listings work ;-)\n\n\u003e because it ends in delimiter we can assume it\u0027s a subdir\n\nThis was the assumption I was questioning -- specifically, if you have a container with objects\n\n obj\n subdir/\n subdir/obj\n\nthen issue a ?delimiter\u003d/ query, I couldn\u0027t remember whether we\u0027d get one or *two* entries for subdir/ -- turns out it\u0027s just the one, and the object \"subdir/\" doesn\u0027t show up until you do a ?delimiter\u003d/\u0026prefix\u003dsubdir/ query.\n\nI think we can just drop this clause -- it\u0027ll be a good bit cleaner and no less correct.","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"}],"test/unit/proxy/controllers/test_container.py":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"7622ea9888ba74772e61ed34fc84a43727b05c5d","unresolved":true,"context_lines":[{"line_number":1070,"context_line":"            (200, sr_dicts, root_shard_resp_hdrs),"},{"line_number":1071,"context_line":"            (200, [sr_0_obj, subdir], shard_resp_hdrs),"},{"line_number":1072,"context_line":"            (200, [], shard_resp_hdrs),"},{"line_number":1073,"context_line":"            (200, [], shard_resp_hdrs),"},{"line_number":1074,"context_line":"            (200, [sr_2_obj], shard_resp_hdrs)"},{"line_number":1075,"context_line":"        ]"},{"line_number":1076,"context_line":"        expected_requests \u003d ["}],"source_content_type":"text/x-python","patch_set":2,"id":"3d40bfa4_22bad7e2","line":1073,"updated":"2022-04-13 21:41:55.000000000","message":"so this patch... makes EXTRA requests?  that\u0027s going the wrong way ;)\n\n\tStopIteration (txn: tx29254e2b2c3b445686045-006257407f)\n\ttest ERROR: ERROR with Container server 10.0.0.5:1005/sda re: Trying to GET /v1/.shards_a/c_: \n\tTraceback (most recent call last):\n\t  File \"/home/vagrant/swift/swift/proxy/controllers/base.py\", line 1368, in _make_node_request\n\t    query_string\u003dself.req_query_string)\n\t  File \"/home/vagrant/swift/swift/common/bufferedhttp.py\", line 281, in http_connect\n\t    ipaddr, port, method, path, headers, query_string, ssl)\n\t  File \"/home/vagrant/swift/test/unit/__init__.py\", line 960, in connect\n\t    i, status \u003d next(conn_id_and_code_iter)\n\tStopIteration (txn: tx29254e2b2c3b445686045-006257407f)\n\ttest ERROR: Container GET returning 503 for [] (txn: tx29254e2b2c3b445686045-006257407f)\n\ttest WARNING: Failed to get container listing from /v1/a/c?states\u003dlisting\u0026delimiter\u003d%2F\u0026format\u003djson: 503 (txn: tx29254e2b2c3b445686045-006257407f)\n\ttest ERROR: Aborting listing from shards due to bad response: [200, 200, 200, 200, 503] (txn: tx29254e2b2c3b445686045-006257407f)\n\tFAIL\n\n\t\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\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\tFAIL: test_GET_sharded_container_with_delimiter (test.unit.proxy.controllers.test_container.TestContainerController)\n\t----------------------------------------------------------------------\n\tTraceback (most recent call last):\n\t  File \"/home/vagrant/swift/test/unit/proxy/controllers/test_container.py\", line 1096, in test_GET_sharded_container_with_delimiter\n\t    query_string\u003d\u0027?delimiter\u003d/\u0027)\n\t  File \"/home/vagrant/swift/test/unit/proxy/controllers/test_container.py\", line 508, in _check_GET_shard_listing\n\t    resp \u003d request.get_response(self.app)\n\t  File \"/usr/lib/python2.7/contextlib.py\", line 24, in __exit__\n\t    self.gen.next()\n\t  File \"/home/vagrant/swift/test/unit/__init__.py\", line 1036, in mocked_http_conn\n\t    \u0027%r\u0027 % (req,) for req in fake_conn.unexpected_requests))\n\tAssertionError: unexpected requests:\n\t((u\u002710.0.0.1\u0027, 1001, \u0027GET\u0027, \u0027/sdb/0/.shards_a/c_\u0027, {\u0027Host\u0027: \u0027localhost:80\u0027, \u0027User-Agent\u0027: \u0027proxy-server 203905\u0027, \u0027Connection\u0027: \u0027close\u0027, \u0027X-Timestamp\u0027: \u00271649885311.33224\u0027, \u0027X-Backend-Record-Type\u0027: \u0027auto\u0027, \u0027X-Trans-Id\u0027: \u0027tx29254e2b2c3b445686045-006257407f\u0027, \u0027Referer\u0027: \u0027GET http://localhost/v1/.shards_a/c_?end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, \u0027X-Backend-Storage-Policy-Index\u0027: \u00270\u0027}, \u0027end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, False), {})\n\t  ((u\u002710.0.0.0\u0027, 1000, \u0027GET\u0027, \u0027/sda/0/.shards_a/c_\u0027, {\u0027Host\u0027: \u0027localhost:80\u0027, \u0027User-Agent\u0027: \u0027proxy-server 203905\u0027, \u0027Connection\u0027: \u0027close\u0027, \u0027X-Timestamp\u0027: \u00271649885311.33224\u0027, \u0027X-Backend-Record-Type\u0027: \u0027auto\u0027, \u0027X-Trans-Id\u0027: \u0027tx29254e2b2c3b445686045-006257407f\u0027, \u0027Referer\u0027: \u0027GET http://localhost/v1/.shards_a/c_?end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, \u0027X-Backend-Storage-Policy-Index\u0027: \u00270\u0027}, \u0027end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, False), {})\n\t  ((u\u002710.0.0.2\u0027, 1002, \u0027GET\u0027, \u0027/sdc/0/.shards_a/c_\u0027, {\u0027Host\u0027: \u0027localhost:80\u0027, \u0027User-Agent\u0027: \u0027proxy-server 203905\u0027, \u0027Connection\u0027: \u0027close\u0027, \u0027X-Timestamp\u0027: \u00271649885311.33224\u0027, \u0027X-Backend-Record-Type\u0027: \u0027auto\u0027, \u0027X-Trans-Id\u0027: \u0027tx29254e2b2c3b445686045-006257407f\u0027, \u0027Referer\u0027: \u0027GET http://localhost/v1/.shards_a/c_?end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, \u0027X-Backend-Storage-Policy-Index\u0027: \u00270\u0027}, \u0027end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, False), {})\n\t  ((\u002710.0.0.3\u0027, 1003, \u0027GET\u0027, \u0027/sda/0/.shards_a/c_\u0027, {\u0027Host\u0027: \u0027localhost:80\u0027, \u0027User-Agent\u0027: \u0027proxy-server 203905\u0027, \u0027Connection\u0027: \u0027close\u0027, \u0027X-Timestamp\u0027: \u00271649885311.33224\u0027, \u0027X-Backend-Record-Type\u0027: \u0027auto\u0027, \u0027X-Trans-Id\u0027: \u0027tx29254e2b2c3b445686045-006257407f\u0027, \u0027Referer\u0027: \u0027GET http://localhost/v1/.shards_a/c_?end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, \u0027X-Backend-Storage-Policy-Index\u0027: \u00270\u0027}, \u0027end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, False), {})\n\t  ((\u002710.0.0.4\u0027, 1004, \u0027GET\u0027, \u0027/sda/0/.shards_a/c_\u0027, {\u0027Host\u0027: \u0027localhost:80\u0027, \u0027User-Agent\u0027: \u0027proxy-server 203905\u0027, \u0027Connection\u0027: \u0027close\u0027, \u0027X-Timestamp\u0027: \u00271649885311.33224\u0027, \u0027X-Backend-Record-Type\u0027: \u0027auto\u0027, \u0027X-Trans-Id\u0027: \u0027tx29254e2b2c3b445686045-006257407f\u0027, \u0027Referer\u0027: \u0027GET http://localhost/v1/.shards_a/c_?end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, \u0027X-Backend-Storage-Policy-Index\u0027: \u00270\u0027}, \u0027end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, False), {})\n\t  ((\u002710.0.0.5\u0027, 1005, \u0027GET\u0027, \u0027/sda/0/.shards_a/c_\u0027, {\u0027Host\u0027: \u0027localhost:80\u0027, \u0027User-Agent\u0027: \u0027proxy-server 203905\u0027, \u0027Connection\u0027: \u0027close\u0027, \u0027X-Timestamp\u0027: \u00271649885311.33224\u0027, \u0027X-Backend-Record-Type\u0027: \u0027auto\u0027, \u0027X-Trans-Id\u0027: \u0027tx29254e2b2c3b445686045-006257407f\u0027, \u0027Referer\u0027: \u0027GET http://localhost/v1/.shards_a/c_?end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, \u0027X-Backend-Storage-Policy-Index\u0027: \u00270\u0027}, \u0027end_marker\u003d\u0026format\u003djson\u0026states\u003dlisting\u0026delimiter\u003d%2F\u0026limit\u003d9997\u0026marker\u003dpumpkin\u0027, False), {})","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9bd279b154bdc054e87e90ebadf4a96803d9951b","unresolved":false,"context_lines":[{"line_number":1070,"context_line":"            (200, sr_dicts, root_shard_resp_hdrs),"},{"line_number":1071,"context_line":"            (200, [sr_0_obj, subdir], shard_resp_hdrs),"},{"line_number":1072,"context_line":"            (200, [], shard_resp_hdrs),"},{"line_number":1073,"context_line":"            (200, [], shard_resp_hdrs),"},{"line_number":1074,"context_line":"            (200, [sr_2_obj], shard_resp_hdrs)"},{"line_number":1075,"context_line":"        ]"},{"line_number":1076,"context_line":"        expected_requests \u003d ["}],"source_content_type":"text/x-python","patch_set":2,"id":"87cd4843_768dddec","line":1073,"in_reply_to":"3600a476_582d1815","updated":"2022-06-15 00:24:27.000000000","message":"Done","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"4208d5fdf8d5df06d6e0c5ab81d52b051212e17d","unresolved":true,"context_lines":[{"line_number":1070,"context_line":"            (200, sr_dicts, root_shard_resp_hdrs),"},{"line_number":1071,"context_line":"            (200, [sr_0_obj, subdir], shard_resp_hdrs),"},{"line_number":1072,"context_line":"            (200, [], shard_resp_hdrs),"},{"line_number":1073,"context_line":"            (200, [], shard_resp_hdrs),"},{"line_number":1074,"context_line":"            (200, [sr_2_obj], shard_resp_hdrs)"},{"line_number":1075,"context_line":"        ]"},{"line_number":1076,"context_line":"        expected_requests \u003d ["}],"source_content_type":"text/x-python","patch_set":2,"id":"3600a476_582d1815","line":1073,"in_reply_to":"3d40bfa4_22bad7e2","updated":"2022-04-13 22:00:18.000000000","message":"Eh? We added *two* new shard ranges, but only needed *one* extra request. This is the failure when you back out the fix, right? So without the fix, we try to talk to *every* shard, and hit a StopIteration/503 when we run out.","commit_id":"5785115510f4070f2ade2ad38046cf4a51ab8441"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9bd279b154bdc054e87e90ebadf4a96803d9951b","unresolved":true,"context_lines":[{"line_number":1030,"context_line":"             % ([200, 200, 503],)], errors[-1:])"},{"line_number":1031,"context_line":""},{"line_number":1032,"context_line":"    def test_GET_sharded_container_with_delimiter(self):"},{"line_number":1033,"context_line":"        shard_bounds \u003d ((\u0027\u0027, \u0027ha/ppy\u0027), (\u0027ha/ppy\u0027, \u0027ha/ptic\u0027),"},{"line_number":1034,"context_line":"                        (\u0027ha/ptic\u0027, \u0027ham\u0027), (\u0027ham\u0027, \u0027pie\u0027), (\u0027pie\u0027, \u0027\u0027))"},{"line_number":1035,"context_line":"        shard_ranges \u003d ["},{"line_number":1036,"context_line":"            ShardRange(\u0027.shards_a/c_%s\u0027 % upper.replace(\u0027/\u0027, \u0027\u0027),"}],"source_content_type":"text/x-python","patch_set":4,"id":"075a97f7_0955db46","line":1033,"updated":"2022-06-15 00:24:27.000000000","message":"ok, so with delim \u0027/\u0027 the sr[0] will return the \u0027ha/\u0027 subdir which means given the bounds of sr[1] we don\u0027t need to query it","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9bd279b154bdc054e87e90ebadf4a96803d9951b","unresolved":true,"context_lines":[{"line_number":1100,"context_line":"        shard_points \u003d (\u0027\u0027, \u0027ha.d\u0027, \u0027ha/ppy\u0027, \u0027ha/ptic\u0027, \u0027ham\u0027, \u0027pie\u0027, \u0027\u0027)"},{"line_number":1101,"context_line":"        shard_bounds \u003d tuple(zip(shard_points, shard_points[1:]))"},{"line_number":1102,"context_line":"        shard_ranges \u003d ["},{"line_number":1103,"context_line":"            ShardRange(\u0027.shards_a/c_%s\u0027 % upper.replace(\u0027/\u0027, \u0027\u0027),"},{"line_number":1104,"context_line":"                       Timestamp.now(), lower, upper)"},{"line_number":1105,"context_line":"            for lower, upper in shard_bounds]"},{"line_number":1106,"context_line":"        sr_dicts \u003d [dict(sr) for sr in shard_ranges]"}],"source_content_type":"text/x-python","patch_set":4,"id":"d17164b9_abb79001","line":1103,"updated":"2022-06-15 00:24:27.000000000","message":"this character swap means our shard names don\u0027t match their bounds\n\nGet listing from /v1/.shards_a/c_happy\n\nmaybe replace(\u0027/\u0027, \u0027-\u0027) would be more obvious","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9bd279b154bdc054e87e90ebadf4a96803d9951b","unresolved":true,"context_lines":[{"line_number":1143,"context_line":"            (200, list(reversed(sr_dicts)), root_shard_resp_hdrs),"},{"line_number":1144,"context_line":"            (200, [sr_5_obj], shard_resp_hdrs),"},{"line_number":1145,"context_line":"            (200, [], shard_resp_hdrs),"},{"line_number":1146,"context_line":"            (200, [subdir], shard_resp_hdrs),"},{"line_number":1147,"context_line":"            (200, [sr_1_obj], shard_resp_hdrs),"},{"line_number":1148,"context_line":"            (200, [sr_0_obj], shard_resp_hdrs),"},{"line_number":1149,"context_line":"        ]"}],"source_content_type":"text/x-python","patch_set":4,"id":"fbce0c27_6a844a4e","line":1146,"updated":"2022-06-15 00:24:27.000000000","message":"so after this one we should be able to skip the whole request to sr(ha/ppy ha/ptic), but with change reverted i see\n\ntest DEBUG: Get listing from /v1/.shards_a/c_haptic?delimiter\u003d%2F\u0026reverse\u003don\u0026format\u003djson\u0026limit\u003d9998\u0026marker\u003dha%2F\u0026end_marker\u003dha%2Fppy {} (txn: tx5da2695de39c4830a3382-0062a9230d)","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9bd279b154bdc054e87e90ebadf4a96803d9951b","unresolved":true,"context_lines":[{"line_number":1145,"context_line":"            (200, [], shard_resp_hdrs),"},{"line_number":1146,"context_line":"            (200, [subdir], shard_resp_hdrs),"},{"line_number":1147,"context_line":"            (200, [sr_1_obj], shard_resp_hdrs),"},{"line_number":1148,"context_line":"            (200, [sr_0_obj], shard_resp_hdrs),"},{"line_number":1149,"context_line":"        ]"},{"line_number":1150,"context_line":"        expected_requests \u003d ["},{"line_number":1151,"context_line":"            (\u0027a/c\u0027, {\u0027X-Backend-Record-Type\u0027: \u0027auto\u0027},"}],"source_content_type":"text/x-python","patch_set":4,"id":"2a46533b_87d762c2","line":1148,"updated":"2022-06-15 00:24:27.000000000","message":"I wish there was something more like FakeSwift, that tied the mock responses back to their shard container names instead of just the order - when I revert the code under test i run out of responses and the test failure looks pretty stupid because the controller code has some get_more_nodes retry logic...","commit_id":"3909d5a47c71b6a11b94600dd202c300d06306e2"}]}
