)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"75ac7dddf6a3c429bfe2963fcb76c56305b76431","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"4c204594_72c0932c","updated":"2026-01-12 21:45:19.000000000","message":"I\u0027d also like to get those obsolete fields removed, who knows what other issue they would cause later on. This patch needs to include a rare case of ``load_all`` though.","commit_id":"250ad4c5e8f4e3f3a3e2dc74fb5db4f2269131eb"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"1a36f6e3585872015c45bf8c519aaf4dae7e3c7a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"55641c0d_86f40480","updated":"2026-01-12 16:48:02.000000000","message":"if we want to go to all the trouble to carry this and then remove it we might want to add some metrics so we can be sure we\u0027ve visited all the dbs and aren\u0027t seeing anymore replication_count\u0027s getting removed.\n\nWe might also have to ensure that shard audit will load all the contexts so we don\u0027t end up with any sleepers.","commit_id":"250ad4c5e8f4e3f3a3e2dc74fb5db4f2269131eb"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"88f31a3d61ff67b1fd29ff2af5b8e654a6b1c88d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"f90c4b64_c98c969c","updated":"2026-01-12 21:41:58.000000000","message":"title has a typo: ``repliation_count-\u003ereplication_count``","commit_id":"250ad4c5e8f4e3f3a3e2dc74fb5db4f2269131eb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"710c8f1c651243aa1e4d63f4964c09cf8e3bdf70","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"0d75d9d9_583bfcb2","updated":"2026-07-31 13:20:27.000000000","message":"I don\u0027t think it is safe to make modifications in load_all\n\nI left some suggestions here 999416: sq? fixups for replication_count removal | https://review.opendev.org/c/openstack/swift/+/999416","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ba81c300fc83af10341519394fc46194f439fb0d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"917a81f9_6c61a36d","updated":"2026-07-31 16:32:36.000000000","message":"+0.9 looks ok to carry with the remaining concern about the TypeError addition","commit_id":"b97875acbc88069c20ad7405b866bc33a041e289"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"3460edb7cd655f94d0e7f5f7db8cc25f1a54d672","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"f68ac5c2_07a98b85","updated":"2026-07-31 18:15:51.000000000","message":"I think this is going to work!\n\n999443: sq? test: reclaim legacy cleaving contexts | https://review.opendev.org/c/openstack/swift/+/999443","commit_id":"52c7a4d055e799edef13fa779b2dcf2286f03797"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c82782c2b9b762e1d47a3b7ab68a41ddc39d0d29","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"15a28fc1_4cb92cfb","updated":"2026-07-31 20:34:01.000000000","message":"i\u0027m pretty confident this change is doing what we need it to.","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"}],"swift/container/sharder.py":[{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"88f31a3d61ff67b1fd29ff2af5b8e654a6b1c88d","unresolved":true,"context_lines":[{"line_number":694,"context_line":"            if key.startswith(\"Context-\") and val:"},{"line_number":695,"context_line":"                try:"},{"line_number":696,"context_line":"                    contexts.append((cls(**json.loads(val)), timestamp))"},{"line_number":697,"context_line":"                except ValueError:"},{"line_number":698,"context_line":"                    continue"},{"line_number":699,"context_line":"        return contexts"},{"line_number":700,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"21b78120_2779709f","line":697,"updated":"2026-01-12 21:41:58.000000000","message":"if a sharded container has already finished cleaving, but got stuck at here (replication_count will cause TypeError exception) for metrics reporting; then the fix in ``load`` won\u0027t remove ``replication_count`` for this container.\n\nif we change this line to\n```\nexcept (ValueError, TypeError):\n```\n\nand then sharder will be unblocked and go through ``load()`` call again to remove ``replication_count``.","commit_id":"250ad4c5e8f4e3f3a3e2dc74fb5db4f2269131eb"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"0ea1c7d71f5b71c9108d6a76259e3ba6724ed937","unresolved":false,"context_lines":[{"line_number":694,"context_line":"            if key.startswith(\"Context-\") and val:"},{"line_number":695,"context_line":"                try:"},{"line_number":696,"context_line":"                    contexts.append((cls(**json.loads(val)), timestamp))"},{"line_number":697,"context_line":"                except ValueError:"},{"line_number":698,"context_line":"                    continue"},{"line_number":699,"context_line":"        return contexts"},{"line_number":700,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"05cdb7fa_94fcfb09","line":697,"in_reply_to":"044ed1fc_bda333d9","updated":"2026-07-31 19:29:10.000000000","message":"Acknowledged","commit_id":"250ad4c5e8f4e3f3a3e2dc74fb5db4f2269131eb"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"a2f308c0563bdfdc59f2ee4c7824f0f3fbf2bf4f","unresolved":true,"context_lines":[{"line_number":694,"context_line":"            if key.startswith(\"Context-\") and val:"},{"line_number":695,"context_line":"                try:"},{"line_number":696,"context_line":"                    contexts.append((cls(**json.loads(val)), timestamp))"},{"line_number":697,"context_line":"                except ValueError:"},{"line_number":698,"context_line":"                    continue"},{"line_number":699,"context_line":"        return contexts"},{"line_number":700,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"597a688b_adc51b0b","line":697,"in_reply_to":"21b78120_2779709f","updated":"2026-07-30 18:11:35.000000000","message":"Added the typerror check so things pass through; but to be certain of the attribute\u0027s removal I copied some of the deletion logic from load over to load_all as well. The new test verifies no errs + deleted attr.","commit_id":"250ad4c5e8f4e3f3a3e2dc74fb5db4f2269131eb"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"25865b0c332df190bc7c0281d0e82c260aa7d382","unresolved":true,"context_lines":[{"line_number":694,"context_line":"            if key.startswith(\"Context-\") and val:"},{"line_number":695,"context_line":"                try:"},{"line_number":696,"context_line":"                    contexts.append((cls(**json.loads(val)), timestamp))"},{"line_number":697,"context_line":"                except ValueError:"},{"line_number":698,"context_line":"                    continue"},{"line_number":699,"context_line":"        return contexts"},{"line_number":700,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"044ed1fc_bda333d9","line":697,"in_reply_to":"36a330e2_f86cc481","updated":"2026-07-31 17:31:12.000000000","message":"True; it\u0027d be super nice if we got the auditor/metrics reporting to do more attribute cleanup faster, but given the concerns with concurrency it might be best to let reclaim get to them assuming they\u0027re not kicking up some other errors that prevent that process.","commit_id":"250ad4c5e8f4e3f3a3e2dc74fb5db4f2269131eb"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"89cba4c0c0fbfd5ff41eb92d9bbe03b313850d26","unresolved":true,"context_lines":[{"line_number":694,"context_line":"            if key.startswith(\"Context-\") and val:"},{"line_number":695,"context_line":"                try:"},{"line_number":696,"context_line":"                    contexts.append((cls(**json.loads(val)), timestamp))"},{"line_number":697,"context_line":"                except ValueError:"},{"line_number":698,"context_line":"                    continue"},{"line_number":699,"context_line":"        return contexts"},{"line_number":700,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"36a330e2_f86cc481","line":697,"in_reply_to":"597a688b_adc51b0b","updated":"2026-07-31 04:45:29.000000000","message":"turns out adding ``TypeError`` to ``except (ValueError):`` is not enough. ``load()`` is only used by active sharding path, but ``load_all()`` is called potentially by many old/completed contexts simply because audit or metrics inspected them.","commit_id":"250ad4c5e8f4e3f3a3e2dc74fb5db4f2269131eb"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"710c8f1c651243aa1e4d63f4964c09cf8e3bdf70","unresolved":true,"context_lines":[{"line_number":699,"context_line":"                        data.pop(\u0027replication_count\u0027)"},{"line_number":700,"context_line":"                        do_repair_writeback \u003d True"},{"line_number":701,"context_line":"                    context \u003d cls(**data)"},{"line_number":702,"context_line":"                except (ValueError, TypeError):"},{"line_number":703,"context_line":"                    continue"},{"line_number":704,"context_line":"                if do_repair_writeback:"},{"line_number":705,"context_line":"                    context.store(broker)"}],"source_content_type":"text/x-python","patch_set":3,"id":"6b337603_b4f961db","line":702,"updated":"2026-07-31 13:20:27.000000000","message":"so here we do tolerate other unexpected keys","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"25865b0c332df190bc7c0281d0e82c260aa7d382","unresolved":true,"context_lines":[{"line_number":699,"context_line":"                        data.pop(\u0027replication_count\u0027)"},{"line_number":700,"context_line":"                        do_repair_writeback \u003d True"},{"line_number":701,"context_line":"                    context \u003d cls(**data)"},{"line_number":702,"context_line":"                except (ValueError, TypeError):"},{"line_number":703,"context_line":"                    continue"},{"line_number":704,"context_line":"                if do_repair_writeback:"},{"line_number":705,"context_line":"                    context.store(broker)"}],"source_content_type":"text/x-python","patch_set":3,"id":"50cc074a_604f7602","line":702,"in_reply_to":"15f3d1d0_8394efc0","updated":"2026-07-31 17:31:12.000000000","message":"I\u0027ve set a reminder that once everything\u0027s been through reclaim ((should) be a week), I\u0027ll have this patch https://review.opendev.org/c/openstack/swift/+/999440 polished and in the forefront of my mind","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"2dfa51105343bfbaa4a48462165e920249f36344","unresolved":true,"context_lines":[{"line_number":699,"context_line":"                        data.pop(\u0027replication_count\u0027)"},{"line_number":700,"context_line":"                        do_repair_writeback \u003d True"},{"line_number":701,"context_line":"                    context \u003d cls(**data)"},{"line_number":702,"context_line":"                except (ValueError, TypeError):"},{"line_number":703,"context_line":"                    continue"},{"line_number":704,"context_line":"                if do_repair_writeback:"},{"line_number":705,"context_line":"                    context.store(broker)"}],"source_content_type":"text/x-python","patch_set":3,"id":"15f3d1d0_8394efc0","line":702,"in_reply_to":"45713f6b_ed4442d4","updated":"2026-07-31 16:41:40.000000000","message":"the addition of TypeError is not covered by tests\n\nI think it is a good idea to allow load_all to ignore bad contexts and return all the good contexts if another unexpected key were to raise a TypeError - we still want to report and audit the good ones.\n\nHowever, I\u0027d suggest that could be a different patch, and it should log a warning if a TypeError is raised.","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c82782c2b9b762e1d47a3b7ab68a41ddc39d0d29","unresolved":false,"context_lines":[{"line_number":699,"context_line":"                        data.pop(\u0027replication_count\u0027)"},{"line_number":700,"context_line":"                        do_repair_writeback \u003d True"},{"line_number":701,"context_line":"                    context \u003d cls(**data)"},{"line_number":702,"context_line":"                except (ValueError, TypeError):"},{"line_number":703,"context_line":"                    continue"},{"line_number":704,"context_line":"                if do_repair_writeback:"},{"line_number":705,"context_line":"                    context.store(broker)"}],"source_content_type":"text/x-python","patch_set":3,"id":"a5d6f886_eaab7749","line":702,"in_reply_to":"50cc074a_604f7602","updated":"2026-07-31 20:34:01.000000000","message":"honestly i\u0027m pretty skeptical blanket TypeError here:\n\n999440: container: ignore invalid cleaving context metadata | https://review.opendev.org/c/openstack/swift/+/999440","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"ba81c300fc83af10341519394fc46194f439fb0d","unresolved":true,"context_lines":[{"line_number":699,"context_line":"                        data.pop(\u0027replication_count\u0027)"},{"line_number":700,"context_line":"                        do_repair_writeback \u003d True"},{"line_number":701,"context_line":"                    context \u003d cls(**data)"},{"line_number":702,"context_line":"                except (ValueError, TypeError):"},{"line_number":703,"context_line":"                    continue"},{"line_number":704,"context_line":"                if do_repair_writeback:"},{"line_number":705,"context_line":"                    context.store(broker)"}],"source_content_type":"text/x-python","patch_set":3,"id":"45713f6b_ed4442d4","line":702,"in_reply_to":"6b337603_b4f961db","updated":"2026-07-31 16:32:36.000000000","message":"this may want some more consideration before carrying - we seem to be making two changes: first to repair the replication_count, second to now catch anything else that raises a TypeError","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"89cba4c0c0fbfd5ff41eb92d9bbe03b313850d26","unresolved":true,"context_lines":[{"line_number":702,"context_line":"                except (ValueError, TypeError):"},{"line_number":703,"context_line":"                    continue"},{"line_number":704,"context_line":"                if do_repair_writeback:"},{"line_number":705,"context_line":"                    context.store(broker)"},{"line_number":706,"context_line":"                    timestamp \u003d ("},{"line_number":707,"context_line":"                        broker.get_sharding_sysmeta_with_timestamps()[key][1])"},{"line_number":708,"context_line":"                contexts.append((context, timestamp))"}],"source_content_type":"text/x-python","patch_set":3,"id":"05c9022e_560ee058","line":705,"updated":"2026-07-31 04:45:29.000000000","message":"``get_sharding_sysmeta_with_timestamps`` takes a metadata snapshot, and here serializes that snapshot back through ``context.store()``, which assigns ``Timestamp.now()``.\n\nThere are two consequences:\n1. If another replicator updates that context after the snapshot but before this write, the repair’s newer timestamp can overwrite those newer context fields with the stale snapshot. this is a very small function, chances are low though.\n2. Even without concurrency, it changes the context’s logical last-modified time to “now.”\n\nThis probably is not an issue for load() since the active sharding will overwrite CleaveContext later anyway.","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"710c8f1c651243aa1e4d63f4964c09cf8e3bdf70","unresolved":true,"context_lines":[{"line_number":702,"context_line":"                except (ValueError, TypeError):"},{"line_number":703,"context_line":"                    continue"},{"line_number":704,"context_line":"                if do_repair_writeback:"},{"line_number":705,"context_line":"                    context.store(broker)"},{"line_number":706,"context_line":"                    timestamp \u003d ("},{"line_number":707,"context_line":"                        broker.get_sharding_sysmeta_with_timestamps()[key][1])"},{"line_number":708,"context_line":"                contexts.append((context, timestamp))"}],"source_content_type":"text/x-python","patch_set":3,"id":"bf585493_ac74e34d","line":705,"in_reply_to":"05c9022e_560ee058","updated":"2026-07-31 13:20:27.000000000","message":"\u003e chances are low though\n...which is a massive scale system means \"this will happen\"\n\nIMHO a specific sharder process that is processing a DB replica with id X should NOT be modifying contexts whose ref binds them to a different DB replica, e.g. with id Y. We can be reasonably confident that only one sharder process at a time will do read-modify-write of the context metadata with ref X in DB with id X. We have to allow for another sharder process to be concurrently doing a read-modify-write of the context metadata with ref Y in DB with id Y.\n\nWe only need ``load_all`` to successfully load for the purposes of progress reporting and auditing. We don\u0027t need it for fix the context; the fix can be left to when a sharder is handling the DB whose id is bound to the context and calls ``load``.\n\nOnce sharding has completed in a context, the audit may use the results from ``load_all` to delete the context, so stale polluted contexts should be eventually removed entirely, without being specifically modified to remove ``replication_count``.","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"25865b0c332df190bc7c0281d0e82c260aa7d382","unresolved":false,"context_lines":[{"line_number":702,"context_line":"                except (ValueError, TypeError):"},{"line_number":703,"context_line":"                    continue"},{"line_number":704,"context_line":"                if do_repair_writeback:"},{"line_number":705,"context_line":"                    context.store(broker)"},{"line_number":706,"context_line":"                    timestamp \u003d ("},{"line_number":707,"context_line":"                        broker.get_sharding_sysmeta_with_timestamps()[key][1])"},{"line_number":708,"context_line":"                contexts.append((context, timestamp))"}],"source_content_type":"text/x-python","patch_set":3,"id":"af52ce97_3e8df15e","line":705,"in_reply_to":"bf585493_ac74e34d","updated":"2026-07-31 17:31:12.000000000","message":"Acknowledged","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"3460edb7cd655f94d0e7f5f7db8cc25f1a54d672","unresolved":true,"context_lines":[{"line_number":727,"context_line":"        data \u003d json.loads(data) if data else {}"},{"line_number":728,"context_line":"        data[\u0027ref\u0027] \u003d ref"},{"line_number":729,"context_line":"        data[\u0027max_row\u0027] \u003d brokers[0].get_max_row()"},{"line_number":730,"context_line":"        ctx \u003d cls._safe_load(broker, data, repair\u003dTrue)"},{"line_number":731,"context_line":"        return ctx"},{"line_number":732,"context_line":""},{"line_number":733,"context_line":"    def store(self, broker):"}],"source_content_type":"text/x-python","patch_set":6,"id":"0b701409_d232b992","line":730,"updated":"2026-07-31 18:15:51.000000000","message":"the reason repair is safe here is because this database-replica \"owns\" this context - so it alone can increment the timestamp and write back","commit_id":"52c7a4d055e799edef13fa779b2dcf2286f03797"},{"author":{"_account_id":34930,"name":"Jianjian Huo","email":"jhuo@nvidia.com","username":"jhuo"},"change_message_id":"0ea1c7d71f5b71c9108d6a76259e3ba6724ed937","unresolved":false,"context_lines":[{"line_number":727,"context_line":"        data \u003d json.loads(data) if data else {}"},{"line_number":728,"context_line":"        data[\u0027ref\u0027] \u003d ref"},{"line_number":729,"context_line":"        data[\u0027max_row\u0027] \u003d brokers[0].get_max_row()"},{"line_number":730,"context_line":"        ctx \u003d cls._safe_load(broker, data, repair\u003dTrue)"},{"line_number":731,"context_line":"        return ctx"},{"line_number":732,"context_line":""},{"line_number":733,"context_line":"    def store(self, broker):"}],"source_content_type":"text/x-python","patch_set":6,"id":"218789b5_e3fb07bf","line":730,"in_reply_to":"0b701409_d232b992","updated":"2026-07-31 19:29:10.000000000","message":"it\u0027s relatively safe here. but turns out we don\u0027t even need to rewrite the repaired CleaveContext again.\n\nif active sharding DB runs into traceback in load(), with just popping out replication_count in CleavingContext.load():\n  1. replication_count is removed in memory.\n  2. Construction succeeds, so sharding continues.\n  3. The next context.store() serializes the current schema without replication_count.\n\nhttps://review.opendev.org/c/openstack/swift/+/999447","commit_id":"52c7a4d055e799edef13fa779b2dcf2286f03797"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c82782c2b9b762e1d47a3b7ab68a41ddc39d0d29","unresolved":true,"context_lines":[{"line_number":715,"context_line":"        ref \u003d cls._make_ref(brokers[0])"},{"line_number":716,"context_line":"        data \u003d brokers[-1].get_sharding_sysmeta(\u0027Context-\u0027 + ref)"},{"line_number":717,"context_line":"        data \u003d json.loads(data) if data else {}"},{"line_number":718,"context_line":"        data.pop(\u0027replication_count\u0027, None)"},{"line_number":719,"context_line":"        data[\u0027ref\u0027] \u003d ref"},{"line_number":720,"context_line":"        data[\u0027max_row\u0027] \u003d brokers[0].get_max_row()"},{"line_number":721,"context_line":"        return cls(**data)"}],"source_content_type":"text/x-python","patch_set":10,"id":"f5097786_d9d2e89f","line":718,"updated":"2026-07-31 20:34:01.000000000","message":"maybe not worth DRYing out for a DNM patch but I sort of liked SSoT from `_safe_load`","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b2ed66fe7c6c2de6aff9785d37d29806d8de9bb5","unresolved":true,"context_lines":[{"line_number":715,"context_line":"        ref \u003d cls._make_ref(brokers[0])"},{"line_number":716,"context_line":"        data \u003d brokers[-1].get_sharding_sysmeta(\u0027Context-\u0027 + ref)"},{"line_number":717,"context_line":"        data \u003d json.loads(data) if data else {}"},{"line_number":718,"context_line":"        data.pop(\u0027replication_count\u0027, None)"},{"line_number":719,"context_line":"        data[\u0027ref\u0027] \u003d ref"},{"line_number":720,"context_line":"        data[\u0027max_row\u0027] \u003d brokers[0].get_max_row()"},{"line_number":721,"context_line":"        return cls(**data)"}],"source_content_type":"text/x-python","patch_set":10,"id":"157ddb74_765142d0","line":718,"in_reply_to":"f5097786_d9d2e89f","updated":"2026-08-03 07:39:20.000000000","message":"+1 nice to see ``_safe_load`` was retained","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"}],"test/unit/container/test_sharder.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"710c8f1c651243aa1e4d63f4964c09cf8e3bdf70","unresolved":true,"context_lines":[{"line_number":8382,"context_line":"            ctx.delete(broker)"},{"line_number":8383,"context_line":"        self.assertEqual([], CleavingContext.load_all(broker))"},{"line_number":8384,"context_line":""},{"line_number":8385,"context_line":"    def test_store_modify_attributes_load_all(self):"},{"line_number":8386,"context_line":"        broker \u003d self._make_sharding_broker()"},{"line_number":8387,"context_line":"        db_id \u003d broker.get_brokers()[0].get_info()[\u0027id\u0027]"},{"line_number":8388,"context_line":"        ctx \u003d CleavingContext(db_id, \u0027curs\u0027, 12, 11, 2, True, True)"}],"source_content_type":"text/x-python","patch_set":3,"id":"6fc2880a_b9ba1683","line":8385,"updated":"2026-07-31 13:20:27.000000000","message":"this test would benefit from having more than one context to load, so that it verifies that the loading continues despite a polluted context being found","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"25865b0c332df190bc7c0281d0e82c260aa7d382","unresolved":false,"context_lines":[{"line_number":8382,"context_line":"            ctx.delete(broker)"},{"line_number":8383,"context_line":"        self.assertEqual([], CleavingContext.load_all(broker))"},{"line_number":8384,"context_line":""},{"line_number":8385,"context_line":"    def test_store_modify_attributes_load_all(self):"},{"line_number":8386,"context_line":"        broker \u003d self._make_sharding_broker()"},{"line_number":8387,"context_line":"        db_id \u003d broker.get_brokers()[0].get_info()[\u0027id\u0027]"},{"line_number":8388,"context_line":"        ctx \u003d CleavingContext(db_id, \u0027curs\u0027, 12, 11, 2, True, True)"}],"source_content_type":"text/x-python","patch_set":3,"id":"64e75ce9_3bd596f4","line":8385,"in_reply_to":"6fc2880a_b9ba1683","updated":"2026-07-31 17:31:12.000000000","message":"Done","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"710c8f1c651243aa1e4d63f4964c09cf8e3bdf70","unresolved":true,"context_lines":[{"line_number":8649,"context_line":"        self.assertFalse(new_ctx.misplaced_done)"},{"line_number":8650,"context_line":"        self.assertFalse(new_ctx.cleaving_done)"},{"line_number":8651,"context_line":""},{"line_number":8652,"context_line":"    def test_store_modify_attributes_load(self):"},{"line_number":8653,"context_line":"        # if the CleavingContext constructor interface ever changes we may have"},{"line_number":8654,"context_line":"        # obsolete attributes persisted in JSON metadata; verify that obsolete"},{"line_number":8655,"context_line":"        # attributes are ignored."}],"source_content_type":"text/x-python","patch_set":3,"id":"fa0bf57c_e0cb19de","line":8652,"updated":"2026-07-31 13:20:27.000000000","message":"this is fine for a patch that we don\u0027t intend to merge upstream.\n\nIf we were merging upstream I\u0027d suggest a test that verifies that any other unexpected key will still raise an error.","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"25865b0c332df190bc7c0281d0e82c260aa7d382","unresolved":false,"context_lines":[{"line_number":8649,"context_line":"        self.assertFalse(new_ctx.misplaced_done)"},{"line_number":8650,"context_line":"        self.assertFalse(new_ctx.cleaving_done)"},{"line_number":8651,"context_line":""},{"line_number":8652,"context_line":"    def test_store_modify_attributes_load(self):"},{"line_number":8653,"context_line":"        # if the CleavingContext constructor interface ever changes we may have"},{"line_number":8654,"context_line":"        # obsolete attributes persisted in JSON metadata; verify that obsolete"},{"line_number":8655,"context_line":"        # attributes are ignored."}],"source_content_type":"text/x-python","patch_set":3,"id":"5fcb7328_07ad6ba1","line":8652,"in_reply_to":"fa0bf57c_e0cb19de","updated":"2026-07-31 17:31:12.000000000","message":"Acknowledged","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"710c8f1c651243aa1e4d63f4964c09cf8e3bdf70","unresolved":true,"context_lines":[{"line_number":8677,"context_line":""},{"line_number":8678,"context_line":"        # and it\u0027s really gone"},{"line_number":8679,"context_line":"        data \u003d json.loads(broker.metadata[key][0])"},{"line_number":8680,"context_line":"        self.assertNotIn(\u0027replication_count\u0027, data)"},{"line_number":8681,"context_line":""},{"line_number":8682,"context_line":"    def test_load_modify_store_load(self):"},{"line_number":8683,"context_line":"        broker \u003d self._make_sharding_broker()"}],"source_content_type":"text/x-python","patch_set":3,"id":"4d0b6e64_8f95b785","line":8680,"updated":"2026-07-31 13:20:27.000000000","message":"better to assert the whole dict to guard against unexpected modifications","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"25865b0c332df190bc7c0281d0e82c260aa7d382","unresolved":false,"context_lines":[{"line_number":8677,"context_line":""},{"line_number":8678,"context_line":"        # and it\u0027s really gone"},{"line_number":8679,"context_line":"        data \u003d json.loads(broker.metadata[key][0])"},{"line_number":8680,"context_line":"        self.assertNotIn(\u0027replication_count\u0027, data)"},{"line_number":8681,"context_line":""},{"line_number":8682,"context_line":"    def test_load_modify_store_load(self):"},{"line_number":8683,"context_line":"        broker \u003d self._make_sharding_broker()"}],"source_content_type":"text/x-python","patch_set":3,"id":"fed00bda_6861f637","line":8680,"in_reply_to":"4d0b6e64_8f95b785","updated":"2026-07-31 17:31:12.000000000","message":"Acknowledged","commit_id":"5e1cfded35733f32e6e55619eb3b9441c2923b6f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c82782c2b9b762e1d47a3b7ab68a41ddc39d0d29","unresolved":true,"context_lines":[{"line_number":8391,"context_line":"        for ctx in contexts:"},{"line_number":8392,"context_line":"            data \u003d dict(ctx, replication_count\u003d\u0027obsolete_value\u0027)"},{"line_number":8393,"context_line":"            broker.set_sharding_sysmeta("},{"line_number":8394,"context_line":"                \u0027Context-\u0027 + ctx.ref, json.dumps(data))"},{"line_number":8395,"context_line":"        persisted \u003d broker.metadata"},{"line_number":8396,"context_line":""},{"line_number":8397,"context_line":"        # load_all returns all the contexts..."}],"source_content_type":"text/x-python","patch_set":10,"id":"6b28d6d4_d8ad4b71","line":8394,"updated":"2026-07-31 20:34:01.000000000","message":"hmph, to write corrupt metadata the other test uses\n```\n        broker.update_metadata(\n            {key: (json.dumps(data), next(self.ts_iter).internal)})\n```\n\nto me, it\u0027s a little more obviously correct","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"49659ed7d0fbe597a26eb7a9c9de4cdf069b5acf","unresolved":false,"context_lines":[{"line_number":8391,"context_line":"        for ctx in contexts:"},{"line_number":8392,"context_line":"            data \u003d dict(ctx, replication_count\u003d\u0027obsolete_value\u0027)"},{"line_number":8393,"context_line":"            broker.set_sharding_sysmeta("},{"line_number":8394,"context_line":"                \u0027Context-\u0027 + ctx.ref, json.dumps(data))"},{"line_number":8395,"context_line":"        persisted \u003d broker.metadata"},{"line_number":8396,"context_line":""},{"line_number":8397,"context_line":"        # load_all returns all the contexts..."}],"source_content_type":"text/x-python","patch_set":10,"id":"baddf322_4cc1bd6a","line":8394,"in_reply_to":"6b28d6d4_d8ad4b71","updated":"2026-07-31 21:32:35.000000000","message":"Done","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c82782c2b9b762e1d47a3b7ab68a41ddc39d0d29","unresolved":true,"context_lines":[{"line_number":8392,"context_line":"            data \u003d dict(ctx, replication_count\u003d\u0027obsolete_value\u0027)"},{"line_number":8393,"context_line":"            broker.set_sharding_sysmeta("},{"line_number":8394,"context_line":"                \u0027Context-\u0027 + ctx.ref, json.dumps(data))"},{"line_number":8395,"context_line":"        persisted \u003d broker.metadata"},{"line_number":8396,"context_line":""},{"line_number":8397,"context_line":"        # load_all returns all the contexts..."},{"line_number":8398,"context_line":"        actual_loaded \u003d CleavingContext.load_all(broker)"}],"source_content_type":"text/x-python","patch_set":10,"id":"b21b16cf_d7dde3d9","line":8395,"updated":"2026-07-31 20:34:01.000000000","message":"my just something here to verify `replication_count` is in persisted as a sanity","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"49659ed7d0fbe597a26eb7a9c9de4cdf069b5acf","unresolved":false,"context_lines":[{"line_number":8392,"context_line":"            data \u003d dict(ctx, replication_count\u003d\u0027obsolete_value\u0027)"},{"line_number":8393,"context_line":"            broker.set_sharding_sysmeta("},{"line_number":8394,"context_line":"                \u0027Context-\u0027 + ctx.ref, json.dumps(data))"},{"line_number":8395,"context_line":"        persisted \u003d broker.metadata"},{"line_number":8396,"context_line":""},{"line_number":8397,"context_line":"        # load_all returns all the contexts..."},{"line_number":8398,"context_line":"        actual_loaded \u003d CleavingContext.load_all(broker)"}],"source_content_type":"text/x-python","patch_set":10,"id":"55477807_6fcff789","line":8395,"in_reply_to":"b21b16cf_d7dde3d9","updated":"2026-07-31 21:32:35.000000000","message":"Done","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c82782c2b9b762e1d47a3b7ab68a41ddc39d0d29","unresolved":true,"context_lines":[{"line_number":8649,"context_line":"    def test_store_modify_attributes_load(self):"},{"line_number":8650,"context_line":"        # if the CleavingContext constructor interface ever changes we may have"},{"line_number":8651,"context_line":"        # obsolete attributes persisted in JSON metadata; verify that obsolete"},{"line_number":8652,"context_line":"        # attributes are ignored."},{"line_number":8653,"context_line":"        broker \u003d self._make_sharding_broker()"},{"line_number":8654,"context_line":"        db_id \u003d broker.get_brokers()[0].get_info()[\u0027id\u0027]"},{"line_number":8655,"context_line":"        ctx \u003d CleavingContext(db_id, \u0027curs\u0027, 12, 11, 2, True, True)"}],"source_content_type":"text/x-python","patch_set":10,"id":"99c4249c_cb8dea4c","line":8652,"updated":"2026-07-31 20:34:01.000000000","message":"this comment is overly broad - there is one specific obsolete attribute that is ignored.","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"49659ed7d0fbe597a26eb7a9c9de4cdf069b5acf","unresolved":false,"context_lines":[{"line_number":8649,"context_line":"    def test_store_modify_attributes_load(self):"},{"line_number":8650,"context_line":"        # if the CleavingContext constructor interface ever changes we may have"},{"line_number":8651,"context_line":"        # obsolete attributes persisted in JSON metadata; verify that obsolete"},{"line_number":8652,"context_line":"        # attributes are ignored."},{"line_number":8653,"context_line":"        broker \u003d self._make_sharding_broker()"},{"line_number":8654,"context_line":"        db_id \u003d broker.get_brokers()[0].get_info()[\u0027id\u0027]"},{"line_number":8655,"context_line":"        ctx \u003d CleavingContext(db_id, \u0027curs\u0027, 12, 11, 2, True, True)"}],"source_content_type":"text/x-python","patch_set":10,"id":"735be38c_a29307c8","line":8652,"in_reply_to":"99c4249c_cb8dea4c","updated":"2026-07-31 21:32:35.000000000","message":"Done","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c82782c2b9b762e1d47a3b7ab68a41ddc39d0d29","unresolved":true,"context_lines":[{"line_number":8658,"context_line":""},{"line_number":8659,"context_line":"        key \u003d \u0027X-Container-Sysmeta-Shard-Context-%s\u0027 % db_id"},{"line_number":8660,"context_line":"        data \u003d json.loads(broker.metadata[key][0])"},{"line_number":8661,"context_line":"        data[\u0027replication_count\u0027] \u003d \u0027obsolete_value\u0027"},{"line_number":8662,"context_line":"        broker.update_metadata("},{"line_number":8663,"context_line":"            {key: (json.dumps(data), next(self.ts_iter).internal)})"},{"line_number":8664,"context_line":"        persisted \u003d broker.metadata[key]"}],"source_content_type":"text/x-python","patch_set":10,"id":"a0af919b_d40edea2","line":8661,"updated":"2026-07-31 20:34:01.000000000","message":"here we add `replication_count` to `orig_data` to create `corrupted_data` (which we then place into broker metadata directly)","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"49659ed7d0fbe597a26eb7a9c9de4cdf069b5acf","unresolved":false,"context_lines":[{"line_number":8658,"context_line":""},{"line_number":8659,"context_line":"        key \u003d \u0027X-Container-Sysmeta-Shard-Context-%s\u0027 % db_id"},{"line_number":8660,"context_line":"        data \u003d json.loads(broker.metadata[key][0])"},{"line_number":8661,"context_line":"        data[\u0027replication_count\u0027] \u003d \u0027obsolete_value\u0027"},{"line_number":8662,"context_line":"        broker.update_metadata("},{"line_number":8663,"context_line":"            {key: (json.dumps(data), next(self.ts_iter).internal)})"},{"line_number":8664,"context_line":"        persisted \u003d broker.metadata[key]"}],"source_content_type":"text/x-python","patch_set":10,"id":"4890d0b4_c89df752","line":8661,"in_reply_to":"a0af919b_d40edea2","updated":"2026-07-31 21:32:35.000000000","message":"Acknowledged","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c82782c2b9b762e1d47a3b7ab68a41ddc39d0d29","unresolved":true,"context_lines":[{"line_number":8668,"context_line":"        # replication_count is removed in memory and max_row is updated to"},{"line_number":8669,"context_line":"        # match the DB"},{"line_number":8670,"context_line":"        exp_data \u003d dict(data, max_row\u003d-1)"},{"line_number":8671,"context_line":"        exp_data.pop(\u0027replication_count\u0027)"},{"line_number":8672,"context_line":"        self.assertEqual(exp_data, dict(new_ctx))"},{"line_number":8673,"context_line":""},{"line_number":8674,"context_line":"        # loading does not modify the persisted value"}],"source_content_type":"text/x-python","patch_set":10,"id":"6f5a8310_e78a0fc7","line":8671,"updated":"2026-07-31 20:34:01.000000000","message":"here we remove `replication_count` from `corrupted_data` to proxy back to `orig_data` so we can assert `reloaded_metadata` ~\u003d `orig_data`\n\n... which feels like overly tedious state mutation for the test reviewer to keep track of","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":38368,"name":"Christian Ohanaja","display_name":"Christian Ohanaja","email":"cohanaja@nvidia.com","username":"cohanaja"},"change_message_id":"49659ed7d0fbe597a26eb7a9c9de4cdf069b5acf","unresolved":false,"context_lines":[{"line_number":8668,"context_line":"        # replication_count is removed in memory and max_row is updated to"},{"line_number":8669,"context_line":"        # match the DB"},{"line_number":8670,"context_line":"        exp_data \u003d dict(data, max_row\u003d-1)"},{"line_number":8671,"context_line":"        exp_data.pop(\u0027replication_count\u0027)"},{"line_number":8672,"context_line":"        self.assertEqual(exp_data, dict(new_ctx))"},{"line_number":8673,"context_line":""},{"line_number":8674,"context_line":"        # loading does not modify the persisted value"}],"source_content_type":"text/x-python","patch_set":10,"id":"252f8ead_5dbb8879","line":8671,"in_reply_to":"6f5a8310_e78a0fc7","updated":"2026-07-31 21:32:35.000000000","message":"Done","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"c82782c2b9b762e1d47a3b7ab68a41ddc39d0d29","unresolved":true,"context_lines":[{"line_number":8672,"context_line":"        self.assertEqual(exp_data, dict(new_ctx))"},{"line_number":8673,"context_line":""},{"line_number":8674,"context_line":"        # loading does not modify the persisted value"},{"line_number":8675,"context_line":"        self.assertEqual(persisted, broker.metadata[key])"},{"line_number":8676,"context_line":""},{"line_number":8677,"context_line":"    def test_load_modify_store_load(self):"},{"line_number":8678,"context_line":"        broker \u003d self._make_sharding_broker()"}],"source_content_type":"text/x-python","patch_set":10,"id":"40fe7f63_6fdb2158","line":8675,"updated":"2026-07-31 20:34:01.000000000","message":"I wanted `test_store_modify` to sanity check that if we `_safe_load` the fixed schema get\u0027s persisted when we \"store back the modified context\" ... but I think this name was just like a sequence desciption of what the test does, i.e.\n\ntest_stuff_in_this_order\n1) store (uncorrupt)\n2) modify (corrupt)\n3) load (see pop worked!)","commit_id":"3aa77e68ee23eb6f20e125e44e442725b86b5a02"}]}
