)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"e7340ac4a9fa58b8ec48be62cdc4fc26ffa6caed","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"40e2e672_089151a1","updated":"2026-10-27 00:01:42.000000000","message":"I used `relic_id` to decide whether a superseded update still needs to be published. This seems direct (but arbitrary), and we\u0027re assuming what the container broker wants to do with such update. A generic systags machinery would facilitate a `role\u003dmpu_\u003cmanifest|lifeline\u003e` KV pair might make this change a a little less brittle.","commit_id":"a4ef80b3ec384a822d029a38d96dcd39c77b8403"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7414f5614e50fc76919b287b0c8ba5c48af74826","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"411b0987_b486b96d","updated":"2026-10-27 13:21:18.000000000","message":"Maybe we can construct a probe test to validate this? It might be tricky, because we\u0027d want container servers to be stopped during an object PUT in order to generate multiple async pendings for the same object, but mpu PUTs may (?) rely on container server state checks. However, we could use an internal client to make a non-mpu PUT with the requisite systags header to trigger relic row generation, and then inspect the container db rows after the updater has run to check we have a relic row.","commit_id":"a4ef80b3ec384a822d029a38d96dcd39c77b8403"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"de519422197eb2f2663def55129f617c8c8a668a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"c74b67f8_64f6575c","updated":"2026-10-28 03:19:19.000000000","message":"Thanks for the feedback, Al! The updated PS is primarily concerned with the prob test you had suggested be written. I still need to work through the upgrade story so that `object-updater` doesn\u0027t miss pending updates.","commit_id":"a4ef80b3ec384a822d029a38d96dcd39c77b8403"}],"swift/obj/updater.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b5112c5fa1235d1cb36fe201043b373cbe04b2f8","unresolved":true,"context_lines":[{"line_number":412,"context_line":"    return acct, cont"},{"line_number":413,"context_line":""},{"line_number":414,"context_line":""},{"line_number":415,"context_line":"def has_relic_id(update):"},{"line_number":416,"context_line":"    \"\"\""},{"line_number":417,"context_line":"    Check if the async update data carries a non-empty relic_id systag."},{"line_number":418,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"d7c7fc00_a1d76eb8","line":415,"updated":"2026-10-27 13:17:31.000000000","message":"I might give this a more generic name e.g. ``is_update_required`` because the systags schema is very provisional; ``relic_id`` might not survive as a systags key","commit_id":"a4ef80b3ec384a822d029a38d96dcd39c77b8403"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"de519422197eb2f2663def55129f617c8c8a668a","unresolved":true,"context_lines":[{"line_number":412,"context_line":"    return acct, cont"},{"line_number":413,"context_line":""},{"line_number":414,"context_line":""},{"line_number":415,"context_line":"def has_relic_id(update):"},{"line_number":416,"context_line":"    \"\"\""},{"line_number":417,"context_line":"    Check if the async update data carries a non-empty relic_id systag."},{"line_number":418,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":1,"id":"830e8c6c_de4ae2b7","line":415,"in_reply_to":"d7c7fc00_a1d76eb8","updated":"2026-10-28 03:19:19.000000000","message":"I understand the concern. I went with `is_update_replaceable`: when the result is `True`, it suggests that some other update can replace this one. Otherwise, it must be retained. I think the difficulty comes from the fact that the relevance of an update is not a local a decision. Thoughts?","commit_id":"a4ef80b3ec384a822d029a38d96dcd39c77b8403"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"e7340ac4a9fa58b8ec48be62cdc4fc26ffa6caed","unresolved":true,"context_lines":[{"line_number":417,"context_line":"    Check if the async update data carries a non-empty relic_id systag."},{"line_number":418,"context_line":"    \"\"\""},{"line_number":419,"context_line":"    systags \u003d HeaderKeyDict(update[\u0027headers\u0027]).get(\u0027X-Systags\u0027)"},{"line_number":420,"context_line":"    return bool(param_str_to_dict(systags).get(\u0027relic_id\u0027))"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":""},{"line_number":423,"context_line":"class ObjectUpdater(Daemon):"}],"source_content_type":"text/x-python","patch_set":1,"id":"a0f98d7f_71042550","line":420,"range":{"start_line":420,"start_character":16,"end_line":420,"end_character":33},"updated":"2026-10-27 00:01:42.000000000","message":"Assumes a well-formed `systags`. Time for a `systags` class?","commit_id":"a4ef80b3ec384a822d029a38d96dcd39c77b8403"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"de519422197eb2f2663def55129f617c8c8a668a","unresolved":false,"context_lines":[{"line_number":417,"context_line":"    Check if the async update data carries a non-empty relic_id systag."},{"line_number":418,"context_line":"    \"\"\""},{"line_number":419,"context_line":"    systags \u003d HeaderKeyDict(update[\u0027headers\u0027]).get(\u0027X-Systags\u0027)"},{"line_number":420,"context_line":"    return bool(param_str_to_dict(systags).get(\u0027relic_id\u0027))"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":""},{"line_number":423,"context_line":"class ObjectUpdater(Daemon):"}],"source_content_type":"text/x-python","patch_set":1,"id":"726ab26b_decaa54c","line":420,"range":{"start_line":420,"start_character":16,"end_line":420,"end_character":33},"in_reply_to":"a0f98d7f_71042550","updated":"2026-10-28 03:19:19.000000000","message":"It wouldn\u0027t offer more than a dict. It would be primarily concerned with validation so that malformed `systags` are detected early. I think you\u0027re first suggestion covers that.","commit_id":"a4ef80b3ec384a822d029a38d96dcd39c77b8403"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b5112c5fa1235d1cb36fe201043b373cbe04b2f8","unresolved":true,"context_lines":[{"line_number":417,"context_line":"    Check if the async update data carries a non-empty relic_id systag."},{"line_number":418,"context_line":"    \"\"\""},{"line_number":419,"context_line":"    systags \u003d HeaderKeyDict(update[\u0027headers\u0027]).get(\u0027X-Systags\u0027)"},{"line_number":420,"context_line":"    return bool(param_str_to_dict(systags).get(\u0027relic_id\u0027))"},{"line_number":421,"context_line":""},{"line_number":422,"context_line":""},{"line_number":423,"context_line":"class ObjectUpdater(Daemon):"}],"source_content_type":"text/x-python","patch_set":1,"id":"d2a65b09_e0432bd5","line":420,"range":{"start_line":420,"start_character":16,"end_line":420,"end_character":33},"in_reply_to":"a0f98d7f_71042550","updated":"2026-10-27 13:17:31.000000000","message":"Maybe, but what interface would the class offer beyond a dict?\n\nIf the concern is just parsing malformed systags then other options would be:\n\n- validate the header early as it is received by the object server\n- have a safe_param_str_to_dict that catches exceptions and always returns a dict (but that\u0027s suppressing a bug which isn\u0027t great)","commit_id":"a4ef80b3ec384a822d029a38d96dcd39c77b8403"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b5112c5fa1235d1cb36fe201043b373cbe04b2f8","unresolved":true,"context_lines":[{"line_number":767,"context_line":"                    update \u003d self._load_update(device, update_path)"},{"line_number":768,"context_line":"                    if update is None:"},{"line_number":769,"context_line":"                        continue"},{"line_number":770,"context_line":"                    if superseded and not has_relic_id(update):"},{"line_number":771,"context_line":"                        self.stats.outdated_unlinks +\u003d 1"},{"line_number":772,"context_line":"                        self.logger.increment(\u0027outdated_unlinks\u0027)"},{"line_number":773,"context_line":"                        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"395247d3_21b0e571","line":770,"range":{"start_line":770,"start_character":42,"end_line":770,"end_character":62},"updated":"2026-10-27 13:17:31.000000000","message":"An alternative approach would be to annotate the async pending file name when it is written by the object server, to indicate that it is for an mpu (or more generally that it should not be skipped). \n\ne.g. \u003cdevice\u003e/async_pending/\u003cobj_suffix\u003e/\u003cobj_hash\u003e-\u003ctimestamp1\u003e-mpu\n\nThe advantage would be that the header dict is already available at that point, whereas here we have to unpickle to get the header dict even when it\u0027s not an mpu.\n\nA further advantage might be that as soon as the object server starts to write the new file name format, an object updater that has NOT been upgraded will raise errors at line 733 and (I think, TBC) the async pending file will remain on disk until an upgraded updater daemon does successfully handle it. This avoids us losing essential updates during a rolling upgrade, although it does feel a little weird to knowingly break backwards compatibility.\n\nWe would also need to check for any other tools that parse async pending file names.","commit_id":"a4ef80b3ec384a822d029a38d96dcd39c77b8403"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"de519422197eb2f2663def55129f617c8c8a668a","unresolved":true,"context_lines":[{"line_number":767,"context_line":"                    update \u003d self._load_update(device, update_path)"},{"line_number":768,"context_line":"                    if update is None:"},{"line_number":769,"context_line":"                        continue"},{"line_number":770,"context_line":"                    if superseded and not has_relic_id(update):"},{"line_number":771,"context_line":"                        self.stats.outdated_unlinks +\u003d 1"},{"line_number":772,"context_line":"                        self.logger.increment(\u0027outdated_unlinks\u0027)"},{"line_number":773,"context_line":"                        try:"}],"source_content_type":"text/x-python","patch_set":1,"id":"770c0b3d_4691df18","line":770,"range":{"start_line":770,"start_character":42,"end_line":770,"end_character":62},"in_reply_to":"395247d3_21b0e571","updated":"2026-10-28 03:19:19.000000000","message":"\u003e although it does feel a little weird to knowingly break backwards compatibility.\n\nThat\u0027s my concern, too.\n\nI do agree that the upgrade story needs to be clarified, but I\u0027m hoping that it wouldn\u0027t require an on-disk format change. Let me give it some more thought.","commit_id":"a4ef80b3ec384a822d029a38d96dcd39c77b8403"}]}
