)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":31357,"name":"LEDUC Florian","display_name":"Florian LEDUC","email":"florian.leduc@socgen.com","username":"leducflorian","status":"Société Générale"},"change_message_id":"93adc6a7594e6f6d32dece2c2f1837f7c6ef5522","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"081ae4ec_48ef784f","updated":"2025-11-17 10:41:02.000000000","message":"Perfectly in phase with this enhancement.","commit_id":"6026a0304b5400ee5512865d36ece2a67ea6b1a4"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"2968f757059034777715212f70b657cbf664cb82","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"d3ad2740_51e45cf2","updated":"2026-05-12 15:05:21.000000000","message":"Fixed a typo myself, otherwise looks good!","commit_id":"d3494d53689c262a2f6012c3f17c27bab9e78a12"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5c9d585beb34817b5d79cce07472d30a8714d086","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"5e6c3661_8a5adc10","updated":"2026-05-12 15:23:44.000000000","message":"I think the partitioning of the stores into pre-arranged batches is a bad idea and will result in slower completion if we choose the batches poorly.","commit_id":"d3494d53689c262a2f6012c3f17c27bab9e78a12"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"94dafaab62585965ea38f881ab61283217120a9a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"2eb18aed_1ee0ae8e","updated":"2026-05-13 06:40:36.000000000","message":"Thank you for inputs Dan.","commit_id":"d3494d53689c262a2f6012c3f17c27bab9e78a12"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"14a62abf117eeaafa2baa5756ab42d6257984fd3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"b36a8b3b_bc250372","updated":"2026-05-13 10:38:24.000000000","message":"Just a question inline.","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"436ee1537782949ab0cbb7518b84b3be2c8dcbd8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"c9b20dbf_7a4b5f81","updated":"2026-05-13 14:26:29.000000000","message":"Thank you for inputs Dan, I will think how we can handle the cleanup case you mentioned.","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"2314a973d90d2793cf8f7327b141b66e330c39c3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"a38c4c65_e127c1df","updated":"2026-05-14 08:56:18.000000000","message":"Thank you for review Dan, I have tried to put up cleaning path as we discussed on IRC.","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7d9de68e96060d05060e45da7535a95f01234493","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":8,"id":"f36b3623_2e382ce4","updated":"2026-05-13 14:15:03.000000000","message":"Thanks Abhi, this is looking like I expect. Just a few more things about error recovery.","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"02574f4b878573aad4f7ea2836e2e9ba21d6cd67","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"38b5637e_66550c68","updated":"2026-05-15 12:40:18.000000000","message":"Looks good enough to me to get going on the implementation. Some other details will shake out of that process anyway I\u0027m sure.\n\nThanks Abhi, I think this is going to be a nice improvement!","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"49157cff52d770bb31c479137bb0f9a13d1938b3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"7e11ea32_4c2a723e","updated":"2026-05-18 06:24:17.000000000","message":"Thank you for inputs, I will start implementing it and post 1st draft before writing unit/functional tests for reference.","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"}],"specs/2026.1/approved/glance/parallel-store-imports.rst":[{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"df9232974ef4a8fd3c7eaf78bf3da7258c5bcc45","unresolved":true,"context_lines":[{"line_number":28,"context_line":"When importing an image to multiple stores using the image"},{"line_number":29,"context_line":"import workflow, the current implementation processes stores sequentially."},{"line_number":30,"context_line":"For example, if importing an image to stores A, B, C, D, and E,"},{"line_number":31,"context_line":"the workflow will:"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"1. Import to store A (wait for completion)"},{"line_number":34,"context_line":"2. Import to store B (wait for completion)"}],"source_content_type":"text/x-rst","patch_set":3,"id":"6a50cb0b_a907ee7e","line":31,"range":{"start_line":31,"start_character":17,"end_line":31,"end_character":18},"updated":"2026-01-07 16:13:10.000000000","message":"will be*","commit_id":"3db27f9fd8450687a70d1c38d68771181fb59386"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e29648dddba94a24f98c0deffad574824b439d15","unresolved":false,"context_lines":[{"line_number":28,"context_line":"When importing an image to multiple stores using the image"},{"line_number":29,"context_line":"import workflow, the current implementation processes stores sequentially."},{"line_number":30,"context_line":"For example, if importing an image to stores A, B, C, D, and E,"},{"line_number":31,"context_line":"the workflow will:"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":"1. Import to store A (wait for completion)"},{"line_number":34,"context_line":"2. Import to store B (wait for completion)"}],"source_content_type":"text/x-rst","patch_set":3,"id":"4be33518_aa196a76","line":31,"range":{"start_line":31,"start_character":17,"end_line":31,"end_character":18},"in_reply_to":"6a50cb0b_a907ee7e","updated":"2026-05-11 06:45:56.000000000","message":"Acknowledged","commit_id":"3db27f9fd8450687a70d1c38d68771181fb59386"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"df9232974ef4a8fd3c7eaf78bf3da7258c5bcc45","unresolved":true,"context_lines":[{"line_number":71,"context_line":"   to 3, the stores will be processed in 3 batches:"},{"line_number":72,"context_line":"   - Batch 1: stores 1, 2, 3 (executed in parallel)"},{"line_number":73,"context_line":"   - Batch 2: stores 4, 5, 6 (executed in parallel)"},{"line_number":74,"context_line":"   - Batch 3: store 7 (executed alone)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"   In this case batches will be executed sequentially, but image will be"},{"line_number":77,"context_line":"   imported to stores in each batch will executed in parallel."}],"source_content_type":"text/x-rst","patch_set":3,"id":"3417ddb4_8265d722","line":74,"range":{"start_line":74,"start_character":32,"end_line":74,"end_character":37},"updated":"2026-01-07 16:13:10.000000000","message":"So if stores 1 and 4 are slow compared to stores 2, 3, 5 and 6, this is still going to take a lot of time: batch 1 \u0026 2 will take a long time to finish, even though stores 2, 3, 5 and 6 will be done uploading quickly. Ideally we\u0027d have 3 threads in a pool, and as soon as a store is done with the import, its thread can be reused.\n\nBut I guess this is good enough for a first implementation, and not many users will actually be configuring a lot of different stores.","commit_id":"3db27f9fd8450687a70d1c38d68771181fb59386"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7d9de68e96060d05060e45da7535a95f01234493","unresolved":false,"context_lines":[{"line_number":71,"context_line":"   to 3, the stores will be processed in 3 batches:"},{"line_number":72,"context_line":"   - Batch 1: stores 1, 2, 3 (executed in parallel)"},{"line_number":73,"context_line":"   - Batch 2: stores 4, 5, 6 (executed in parallel)"},{"line_number":74,"context_line":"   - Batch 3: store 7 (executed alone)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"   In this case batches will be executed sequentially, but image will be"},{"line_number":77,"context_line":"   imported to stores in each batch will executed in parallel."}],"source_content_type":"text/x-rst","patch_set":3,"id":"2fa0b207_fec32e48","line":74,"range":{"start_line":74,"start_character":32,"end_line":74,"end_character":37},"in_reply_to":"01b4736e_a0522c54","updated":"2026-05-13 14:15:03.000000000","message":"No, build a _worker pool_ of size `max_parallel_stores` and let the workers consume upload requests from the queue. The queue can be bounded much higher - whatever the max number of stores could be (maybe 32 or something?)\n\nEDIT: looks like the text in the spec is correct :)","commit_id":"3db27f9fd8450687a70d1c38d68771181fb59386"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"065a1b18fcce61f2ea67953eed46bf427f07472e","unresolved":true,"context_lines":[{"line_number":71,"context_line":"   to 3, the stores will be processed in 3 batches:"},{"line_number":72,"context_line":"   - Batch 1: stores 1, 2, 3 (executed in parallel)"},{"line_number":73,"context_line":"   - Batch 2: stores 4, 5, 6 (executed in parallel)"},{"line_number":74,"context_line":"   - Batch 3: store 7 (executed alone)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"   In this case batches will be executed sequentially, but image will be"},{"line_number":77,"context_line":"   imported to stores in each batch will executed in parallel."}],"source_content_type":"text/x-rst","patch_set":3,"id":"36925224_30ca2966","line":74,"range":{"start_line":74,"start_character":32,"end_line":74,"end_character":37},"in_reply_to":"3417ddb4_8265d722","updated":"2026-05-11 02:12:31.000000000","message":"Also, I don\u0027t understand why the batches would not be as follows:\n\nBatch 1: stores 1,2\nBatch 2: stores 3,4\nBatch 3: stores 5,6,7","commit_id":"3db27f9fd8450687a70d1c38d68771181fb59386"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e29648dddba94a24f98c0deffad574824b439d15","unresolved":true,"context_lines":[{"line_number":71,"context_line":"   to 3, the stores will be processed in 3 batches:"},{"line_number":72,"context_line":"   - Batch 1: stores 1, 2, 3 (executed in parallel)"},{"line_number":73,"context_line":"   - Batch 2: stores 4, 5, 6 (executed in parallel)"},{"line_number":74,"context_line":"   - Batch 3: store 7 (executed alone)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"   In this case batches will be executed sequentially, but image will be"},{"line_number":77,"context_line":"   imported to stores in each batch will executed in parallel."}],"source_content_type":"text/x-rst","patch_set":3,"id":"703b8f52_e363b8ce","line":74,"range":{"start_line":74,"start_character":32,"end_line":74,"end_character":37},"in_reply_to":"36925224_30ca2966","updated":"2026-05-11 06:45:56.000000000","message":"Reply because we want the `max_parallel_import` config option to decide how many batches we want to create. Since this is defaulted to 3, it will create batches in 3.","commit_id":"3db27f9fd8450687a70d1c38d68771181fb59386"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"94dafaab62585965ea38f881ab61283217120a9a","unresolved":true,"context_lines":[{"line_number":71,"context_line":"   to 3, the stores will be processed in 3 batches:"},{"line_number":72,"context_line":"   - Batch 1: stores 1, 2, 3 (executed in parallel)"},{"line_number":73,"context_line":"   - Batch 2: stores 4, 5, 6 (executed in parallel)"},{"line_number":74,"context_line":"   - Batch 3: store 7 (executed alone)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"   In this case batches will be executed sequentially, but image will be"},{"line_number":77,"context_line":"   imported to stores in each batch will executed in parallel."}],"source_content_type":"text/x-rst","patch_set":3,"id":"01b4736e_a0522c54","line":74,"range":{"start_line":74,"start_character":32,"end_line":74,"end_character":37},"in_reply_to":"66cb5d01_b8519ca4","updated":"2026-05-13 06:40:36.000000000","message":"So you mean built a queue of size max_parallel_stores and as soon as one import finishes enqueue another one and so on right? I think this approach will also solve Cyril\u0027s concern","commit_id":"3db27f9fd8450687a70d1c38d68771181fb59386"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5c9d585beb34817b5d79cce07472d30a8714d086","unresolved":true,"context_lines":[{"line_number":71,"context_line":"   to 3, the stores will be processed in 3 batches:"},{"line_number":72,"context_line":"   - Batch 1: stores 1, 2, 3 (executed in parallel)"},{"line_number":73,"context_line":"   - Batch 2: stores 4, 5, 6 (executed in parallel)"},{"line_number":74,"context_line":"   - Batch 3: store 7 (executed alone)"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"   In this case batches will be executed sequentially, but image will be"},{"line_number":77,"context_line":"   imported to stores in each batch will executed in parallel."}],"source_content_type":"text/x-rst","patch_set":3,"id":"66cb5d01_b8519ca4","line":74,"range":{"start_line":74,"start_character":32,"end_line":74,"end_character":37},"in_reply_to":"703b8f52_e363b8ce","updated":"2026-05-12 15:23:44.000000000","message":"Pre-batching is a bad idea, IMHO. Use a `queue`, enqueue all the import operations and let a pool of workers consume from the pool in whatever order they can get things done. That will result in the fastest time to completion.","commit_id":"3db27f9fd8450687a70d1c38d68771181fb59386"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"df9232974ef4a8fd3c7eaf78bf3da7258c5bcc45","unresolved":true,"context_lines":[{"line_number":147,"context_line":""},{"line_number":148,"context_line":"With parallel execution (assuming 3 parallel stores):"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"total_time ≈ max(time_store_a, time_store_b, time_store_c) + "},{"line_number":151,"context_line":"            max(time_store_d, time_store_e) + ..."},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"The actual improvement depends on:"}],"source_content_type":"text/x-rst","patch_set":3,"id":"d4c237e6_9de30041","line":150,"range":{"start_line":150,"start_character":59,"end_line":150,"end_character":60},"updated":"2026-01-07 16:13:10.000000000","message":"There is a space at the end of the line","commit_id":"3db27f9fd8450687a70d1c38d68771181fb59386"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e29648dddba94a24f98c0deffad574824b439d15","unresolved":false,"context_lines":[{"line_number":147,"context_line":""},{"line_number":148,"context_line":"With parallel execution (assuming 3 parallel stores):"},{"line_number":149,"context_line":""},{"line_number":150,"context_line":"total_time ≈ max(time_store_a, time_store_b, time_store_c) + "},{"line_number":151,"context_line":"            max(time_store_d, time_store_e) + ..."},{"line_number":152,"context_line":""},{"line_number":153,"context_line":"The actual improvement depends on:"}],"source_content_type":"text/x-rst","patch_set":3,"id":"3933a6cc_79d0b842","line":150,"range":{"start_line":150,"start_character":59,"end_line":150,"end_character":60},"in_reply_to":"d4c237e6_9de30041","updated":"2026-05-11 06:45:56.000000000","message":"Acknowledged","commit_id":"3db27f9fd8450687a70d1c38d68771181fb59386"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5c9d585beb34817b5d79cce07472d30a8714d086","unresolved":true,"context_lines":[{"line_number":54,"context_line":"import path does not do that for per-store writes. Parallelism across"},{"line_number":55,"context_line":"different images (the API spawning each import on a tasks pool) is separate"},{"line_number":56,"context_line":"and does not make one image replicate to several stores at once, which is"},{"line_number":57,"context_line":"the gap this specification addresses."},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"Operators deploying multi-store configurations would benefit from reduced"},{"line_number":60,"context_line":"import times when importing images to multiple backends. This is especially"}],"source_content_type":"text/x-rst","patch_set":7,"id":"4125ddc0_d109329a","line":57,"updated":"2026-05-12 15:23:44.000000000","message":"Ahh, sorry, I thought you were just concerned about multiple separate images being imported at once. But you\u0027re concerned with one image going to multiple stores in parallel, right?","commit_id":"d3494d53689c262a2f6012c3f17c27bab9e78a12"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"94dafaab62585965ea38f881ab61283217120a9a","unresolved":false,"context_lines":[{"line_number":54,"context_line":"import path does not do that for per-store writes. Parallelism across"},{"line_number":55,"context_line":"different images (the API spawning each import on a tasks pool) is separate"},{"line_number":56,"context_line":"and does not make one image replicate to several stores at once, which is"},{"line_number":57,"context_line":"the gap this specification addresses."},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"Operators deploying multi-store configurations would benefit from reduced"},{"line_number":60,"context_line":"import times when importing images to multiple backends. This is especially"}],"source_content_type":"text/x-rst","patch_set":7,"id":"40f671be_ce207300","line":57,"in_reply_to":"4125ddc0_d109329a","updated":"2026-05-13 06:40:36.000000000","message":"yes","commit_id":"d3494d53689c262a2f6012c3f17c27bab9e78a12"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5c9d585beb34817b5d79cce07472d30a8714d086","unresolved":true,"context_lines":[{"line_number":69,"context_line":"Modify the import flow to support parallel execution of imports"},{"line_number":70,"context_line":"within a single image import operation. The implementation will:"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"1. Add a new configuration option `max_parallel_import`"},{"line_number":73,"context_line":"in the `[image_import_opts]` section with a default value of 1. This"},{"line_number":74,"context_line":"controls how many stores can be imported to simultaneously for a single"},{"line_number":75,"context_line":"image. The default value of 1 maintains backward compatibility by using"}],"source_content_type":"text/x-rst","patch_set":7,"id":"561598ce_70146dba","line":72,"updated":"2026-05-12 15:23:44.000000000","message":"I think you should name this something more store-specific to avoid any confusion like I brought initially. Perhaps `max_parallel_stores` or `store_parallelism` or something. I think it\u0027s clear this is for import, since it\u0027s inside `[image_import_opts]`.","commit_id":"d3494d53689c262a2f6012c3f17c27bab9e78a12"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"94dafaab62585965ea38f881ab61283217120a9a","unresolved":false,"context_lines":[{"line_number":69,"context_line":"Modify the import flow to support parallel execution of imports"},{"line_number":70,"context_line":"within a single image import operation. The implementation will:"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"1. Add a new configuration option `max_parallel_import`"},{"line_number":73,"context_line":"in the `[image_import_opts]` section with a default value of 1. This"},{"line_number":74,"context_line":"controls how many stores can be imported to simultaneously for a single"},{"line_number":75,"context_line":"image. The default value of 1 maintains backward compatibility by using"}],"source_content_type":"text/x-rst","patch_set":7,"id":"14482d16_529c1d67","line":72,"in_reply_to":"561598ce_70146dba","updated":"2026-05-13 06:40:36.000000000","message":"Acknowledged","commit_id":"d3494d53689c262a2f6012c3f17c27bab9e78a12"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5c9d585beb34817b5d79cce07472d30a8714d086","unresolved":true,"context_lines":[{"line_number":94,"context_line":"   Location Collection: During parallel imports, each import task"},{"line_number":95,"context_line":"   imports the image data to its respective store and collects the"},{"line_number":96,"context_line":"   location information in a shared data structure. The locations will not"},{"line_number":97,"context_line":"   be saved to the database immediately to avoid race conditions."},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"   Atomic Location Saving: Once all parallel imports in all batches complete"},{"line_number":100,"context_line":"   successfully, a separate task will be executed to collect all locations from"}],"source_content_type":"text/x-rst","patch_set":7,"id":"71d96834_e6bba00d","line":97,"updated":"2026-05-12 15:23:44.000000000","message":"That\u0027s good (and also makes it irrelevant which order we do them in). However, what is the recovery plan if we fail in the middle. How will we realize that we have consumed space in the first few stores?","commit_id":"d3494d53689c262a2f6012c3f17c27bab9e78a12"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"94dafaab62585965ea38f881ab61283217120a9a","unresolved":false,"context_lines":[{"line_number":94,"context_line":"   Location Collection: During parallel imports, each import task"},{"line_number":95,"context_line":"   imports the image data to its respective store and collects the"},{"line_number":96,"context_line":"   location information in a shared data structure. The locations will not"},{"line_number":97,"context_line":"   be saved to the database immediately to avoid race conditions."},{"line_number":98,"context_line":""},{"line_number":99,"context_line":"   Atomic Location Saving: Once all parallel imports in all batches complete"},{"line_number":100,"context_line":"   successfully, a separate task will be executed to collect all locations from"}],"source_content_type":"text/x-rst","patch_set":7,"id":"972be420_7922048a","line":97,"in_reply_to":"71d96834_e6bba00d","updated":"2026-05-13 06:40:36.000000000","message":"I have explained this in point 3 but missed on hwo we will be cleaning the data, adding it in new PS.","commit_id":"d3494d53689c262a2f6012c3f17c27bab9e78a12"}],"specs/2026.2/approved/glance/parallel-store-imports.rst":[{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"14a62abf117eeaafa2baa5756ab42d6257984fd3","unresolved":true,"context_lines":[{"line_number":52,"context_line":"``engine_mode``. ``parallel`` only helps when a flow exposes independent"},{"line_number":53,"context_line":"Taskflow atoms the engine may run at the same time; the current multi-store"},{"line_number":54,"context_line":"import path does not do that for per-store writes. Parallelism across"},{"line_number":55,"context_line":"different images (the API spawning each import on a tasks pool) is separate"},{"line_number":56,"context_line":"and does not make one image replicate to several stores at once, which is"},{"line_number":57,"context_line":"the gap this specification addresses."},{"line_number":58,"context_line":""}],"source_content_type":"text/x-rst","patch_set":8,"id":"3473cde0_c1a64240","line":55,"range":{"start_line":55,"start_character":52,"end_line":55,"end_character":57},"updated":"2026-05-13 10:38:24.000000000","message":"s/tasks/task","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"8ea867a717ed268b207459b64972e75f39781fbb","unresolved":false,"context_lines":[{"line_number":52,"context_line":"``engine_mode``. ``parallel`` only helps when a flow exposes independent"},{"line_number":53,"context_line":"Taskflow atoms the engine may run at the same time; the current multi-store"},{"line_number":54,"context_line":"import path does not do that for per-store writes. Parallelism across"},{"line_number":55,"context_line":"different images (the API spawning each import on a tasks pool) is separate"},{"line_number":56,"context_line":"and does not make one image replicate to several stores at once, which is"},{"line_number":57,"context_line":"the gap this specification addresses."},{"line_number":58,"context_line":""}],"source_content_type":"text/x-rst","patch_set":8,"id":"78e9aebe_f1b8d792","line":55,"range":{"start_line":55,"start_character":52,"end_line":55,"end_character":57},"in_reply_to":"3473cde0_c1a64240","updated":"2026-05-13 14:08:06.000000000","message":"Will fix it in new PS","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"14a62abf117eeaafa2baa5756ab42d6257984fd3","unresolved":true,"context_lines":[{"line_number":77,"context_line":"value to a number greater than 1."},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"2. When parallel imports are enabled (`max_parallel_stores` is more than 1"},{"line_number":80,"context_line":"   and there is more than one target store), the code uses a work queue and"},{"line_number":81,"context_line":"   a worker pool. The pool size is at most ``max_parallel_stores`` (how many"},{"line_number":82,"context_line":"   store imports may run at the same time)."},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"   One import job is one target store. First the flow runs the normal linear"}],"source_content_type":"text/x-rst","patch_set":8,"id":"da59a66c_4dd975e0","line":81,"range":{"start_line":80,"start_character":45,"end_line":81,"end_character":17},"updated":"2026-05-13 10:38:24.000000000","message":"The queue and worker pool are clear at a high level, but how is the worker pool supposed to fit into Taskflow? Will that be one Taskflow step that runs the whole pool inside it, or many parallel Taskflow tasks?","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"2314a973d90d2793cf8f7327b141b66e330c39c3","unresolved":false,"context_lines":[{"line_number":77,"context_line":"value to a number greater than 1."},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"2. When parallel imports are enabled (`max_parallel_stores` is more than 1"},{"line_number":80,"context_line":"   and there is more than one target store), the code uses a work queue and"},{"line_number":81,"context_line":"   a worker pool. The pool size is at most ``max_parallel_stores`` (how many"},{"line_number":82,"context_line":"   store imports may run at the same time)."},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"   One import job is one target store. First the flow runs the normal linear"}],"source_content_type":"text/x-rst","patch_set":8,"id":"5dcc80c1_10ca34b2","line":81,"range":{"start_line":80,"start_character":45,"end_line":81,"end_character":17},"in_reply_to":"47ebb939_b15257f6","updated":"2026-05-14 08:56:18.000000000","message":"Acknowledged","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"8ea867a717ed268b207459b64972e75f39781fbb","unresolved":true,"context_lines":[{"line_number":77,"context_line":"value to a number greater than 1."},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"2. When parallel imports are enabled (`max_parallel_stores` is more than 1"},{"line_number":80,"context_line":"   and there is more than one target store), the code uses a work queue and"},{"line_number":81,"context_line":"   a worker pool. The pool size is at most ``max_parallel_stores`` (how many"},{"line_number":82,"context_line":"   store imports may run at the same time)."},{"line_number":83,"context_line":""},{"line_number":84,"context_line":"   One import job is one target store. First the flow runs the normal linear"}],"source_content_type":"text/x-rst","patch_set":8,"id":"47ebb939_b15257f6","line":81,"range":{"start_line":80,"start_character":45,"end_line":81,"end_character":17},"in_reply_to":"da59a66c_4dd975e0","updated":"2026-05-13 14:08:06.000000000","message":"The queue will be build before the taskflow execution starts and will be passed as input to the new task.","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7d9de68e96060d05060e45da7535a95f01234493","unresolved":true,"context_lines":[{"line_number":86,"context_line":"   into the queue. The jobs do not all run at the same time. Only up to"},{"line_number":87,"context_line":"   ``max_parallel_stores`` store imports are active together; any other jobs"},{"line_number":88,"context_line":"   wait in the queue until a worker is free. When one worker finishes one"},{"line_number":89,"context_line":"   store, it takes the next job from the queue until the queue is empty."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"   Location Collection: While stores run in parallel, each task copies the"},{"line_number":92,"context_line":"   image data to its store and puts the location information into one shared"}],"source_content_type":"text/x-rst","patch_set":8,"id":"8495538f_0c73bc91","line":89,"updated":"2026-05-13 14:15:03.000000000","message":"Yep, exactly. Point of clarification: the worker pool should be global (per API worker) which means if you have two images being imported at once in a single API worker then only `max_parallel_stores` uploads will happen at once across both of them (which is good).","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"436ee1537782949ab0cbb7518b84b3be2c8dcbd8","unresolved":false,"context_lines":[{"line_number":86,"context_line":"   into the queue. The jobs do not all run at the same time. Only up to"},{"line_number":87,"context_line":"   ``max_parallel_stores`` store imports are active together; any other jobs"},{"line_number":88,"context_line":"   wait in the queue until a worker is free. When one worker finishes one"},{"line_number":89,"context_line":"   store, it takes the next job from the queue until the queue is empty."},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"   Location Collection: While stores run in parallel, each task copies the"},{"line_number":92,"context_line":"   image data to its store and puts the location information into one shared"}],"source_content_type":"text/x-rst","patch_set":8,"id":"e3f36340_fdb1b9bd","line":89,"in_reply_to":"8495538f_0c73bc91","updated":"2026-05-13 14:26:29.000000000","message":"Acknowledged","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7d9de68e96060d05060e45da7535a95f01234493","unresolved":true,"context_lines":[{"line_number":106,"context_line":"   Partial failure and cleanup: The import can fail before Atomic Location"},{"line_number":107,"context_line":"   Saving. Then the full image may already exist on some backends, but the"},{"line_number":108,"context_line":"   image record still has no locations in the database. So we must record per"},{"line_number":109,"context_line":"   store: if the write finished, and the location URI (or same kind of"},{"line_number":110,"context_line":"   handle) that we need for delete. We keep this in the same shared object as"},{"line_number":111,"context_line":"   for Location Collection. Later we use that same record for cleanup. On"},{"line_number":112,"context_line":"   failure, the normal revert or failure code must read the record and delete"}],"source_content_type":"text/x-rst","patch_set":8,"id":"1c00adee_95d5bb08","line":109,"range":{"start_line":109,"start_character":58,"end_line":109,"end_character":62},"updated":"2026-05-13 14:15:03.000000000","message":"\"some\" kind?","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"436ee1537782949ab0cbb7518b84b3be2c8dcbd8","unresolved":false,"context_lines":[{"line_number":106,"context_line":"   Partial failure and cleanup: The import can fail before Atomic Location"},{"line_number":107,"context_line":"   Saving. Then the full image may already exist on some backends, but the"},{"line_number":108,"context_line":"   image record still has no locations in the database. So we must record per"},{"line_number":109,"context_line":"   store: if the write finished, and the location URI (or same kind of"},{"line_number":110,"context_line":"   handle) that we need for delete. We keep this in the same shared object as"},{"line_number":111,"context_line":"   for Location Collection. Later we use that same record for cleanup. On"},{"line_number":112,"context_line":"   failure, the normal revert or failure code must read the record and delete"}],"source_content_type":"text/x-rst","patch_set":8,"id":"272f214c_dbe775ad","line":109,"range":{"start_line":109,"start_character":58,"end_line":109,"end_character":62},"in_reply_to":"1c00adee_95d5bb08","updated":"2026-05-13 14:26:29.000000000","message":"Acknowledged","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7d9de68e96060d05060e45da7535a95f01234493","unresolved":true,"context_lines":[{"line_number":111,"context_line":"   for Location Collection. Later we use that same record for cleanup. On"},{"line_number":112,"context_line":"   failure, the normal revert or failure code must read the record and delete"},{"line_number":113,"context_line":"   any orphan image data on the backends (same idea as today, but it must use"},{"line_number":114,"context_line":"   the list built during parallel store jobs)."},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"   Failure behavior is still controlled by the existing"},{"line_number":117,"context_line":"   `all_stores_must_succeed` parameter. If it is True (default): when any"}],"source_content_type":"text/x-rst","patch_set":8,"id":"5c3a957d_b7a93435","line":114,"updated":"2026-05-13 14:15:03.000000000","message":"This is the case if upload fails but the API worker stays alive. What happens if the worker doing this upload is forceably stopped, the machine loses power, network is disconnected? How will we avoid \"leaking\" data on the destination stores that we will not have recorded to clean up?\n\nI suppose we have this problem today but the window is very short between upload completion and recording? This parallel approach will very much increase that potential.\n\nIf we can\u0027t do anything better, what would the manual cleanup look like?","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"2314a973d90d2793cf8f7327b141b66e330c39c3","unresolved":false,"context_lines":[{"line_number":111,"context_line":"   for Location Collection. Later we use that same record for cleanup. On"},{"line_number":112,"context_line":"   failure, the normal revert or failure code must read the record and delete"},{"line_number":113,"context_line":"   any orphan image data on the backends (same idea as today, but it must use"},{"line_number":114,"context_line":"   the list built during parallel store jobs)."},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"   Failure behavior is still controlled by the existing"},{"line_number":117,"context_line":"   `all_stores_must_succeed` parameter. If it is True (default): when any"}],"source_content_type":"text/x-rst","patch_set":8,"id":"a0fc4f85_dd1a2c5a","line":114,"in_reply_to":"0344bd9e_11b481a6","updated":"2026-05-14 08:56:18.000000000","message":"Done","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"436ee1537782949ab0cbb7518b84b3be2c8dcbd8","unresolved":true,"context_lines":[{"line_number":111,"context_line":"   for Location Collection. Later we use that same record for cleanup. On"},{"line_number":112,"context_line":"   failure, the normal revert or failure code must read the record and delete"},{"line_number":113,"context_line":"   any orphan image data on the backends (same idea as today, but it must use"},{"line_number":114,"context_line":"   the list built during parallel store jobs)."},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"   Failure behavior is still controlled by the existing"},{"line_number":117,"context_line":"   `all_stores_must_succeed` parameter. If it is True (default): when any"}],"source_content_type":"text/x-rst","patch_set":8,"id":"6d0f4050_563e6649","line":114,"in_reply_to":"5c3a957d_b7a93435","updated":"2026-05-13 14:26:29.000000000","message":"I need to think on this later case, will update the spec soon. Between any inputs on how to handle this will be appreciated :) \nI am not sure whether having periodic job for this is a good idea.","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"391b063403661d8b8f541de57f38b7397e31d424","unresolved":true,"context_lines":[{"line_number":111,"context_line":"   for Location Collection. Later we use that same record for cleanup. On"},{"line_number":112,"context_line":"   failure, the normal revert or failure code must read the record and delete"},{"line_number":113,"context_line":"   any orphan image data on the backends (same idea as today, but it must use"},{"line_number":114,"context_line":"   the list built during parallel store jobs)."},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"   Failure behavior is still controlled by the existing"},{"line_number":117,"context_line":"   `all_stores_must_succeed` parameter. If it is True (default): when any"}],"source_content_type":"text/x-rst","patch_set":8,"id":"9dc15e8d_ad999638","line":114,"in_reply_to":"6d0f4050_563e6649","updated":"2026-05-13 14:33:16.000000000","message":"I actually don\u0027t know how to handle this.. A periodic task won\u0027t have a record of what to clean up will it? If there\u0027s some sort of residual record then just a glance-manage command would be fine I think. Point is, I\u0027m not sure how to go about identifying the missing bits.\n\nCould we go ahead and add them as locations, but with a flag that says they\u0027re pending/incomplete or something until the upload is complete?","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"663a107130c110fab545d7e914456af8647e0824","unresolved":true,"context_lines":[{"line_number":111,"context_line":"   for Location Collection. Later we use that same record for cleanup. On"},{"line_number":112,"context_line":"   failure, the normal revert or failure code must read the record and delete"},{"line_number":113,"context_line":"   any orphan image data on the backends (same idea as today, but it must use"},{"line_number":114,"context_line":"   the list built during parallel store jobs)."},{"line_number":115,"context_line":""},{"line_number":116,"context_line":"   Failure behavior is still controlled by the existing"},{"line_number":117,"context_line":"   `all_stores_must_succeed` parameter. If it is True (default): when any"}],"source_content_type":"text/x-rst","patch_set":8,"id":"0344bd9e_11b481a6","line":114,"in_reply_to":"9dc15e8d_ad999638","updated":"2026-05-13 14:45:01.000000000","message":"We do have status column in image_locations with default value as active. I think we can store it there as pending and then periodic task or at service startup we can traverse through it and clean them up.","commit_id":"aa3e873f1e75d956d19bdd6fdd6a067d42c0e827"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"db8e60db7c5eb2b9375d615a16802979769ef822","unresolved":true,"context_lines":[{"line_number":137,"context_line":"   to ``active`` when upload to store is finished."},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"   A future enhancement can add an API option or flag to expose ``pending``"},{"line_number":140,"context_line":"   locations (for example for operators who want to see import progress)."},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"3. The default value is 1. This is for backward compatibility: same as"},{"line_number":143,"context_line":"sequential import today. If the operator tried a higher value and wants"}],"source_content_type":"text/x-rst","patch_set":9,"id":"cfdeafe5_cc97dee9","line":140,"updated":"2026-05-14 15:30:34.000000000","message":"I mentioned this in IRC and have been thinking over this a bit since then.\n\nCan we go ahead and use \"pending\" for \"in the queue\" and \"uploading\" for actual uploading? I think this is a small detail, but it will be helpful to know about the progress of the thing, both for debugging and testing but also for later if/when we expose it in the API. So the workflow would be:\n\nFor each store: create a new location, set to pending, add item to the work queue, wait for all the queued items to finish\n\nand then the workers would:\n\n1. Dequeue a work item\n2. Mark the location as `uploading`\n3. Do the upload\n4. Mark the location as `active`\n5. Move on to the next item (goto 1)\n\nTo me, this would be the best indication/recording of status instead of it just being sort of a black box.\n\nIf we don\u0027t want them to be active until the atomic update to active at the end, we could make #4 be \"mark the location as `uploaded`\"\n\nIt seems to me that some use-cases may benefit from an image going `ACTIVE` as soon as one location is uploaded and to have the locations that are finished be visible as soon as they are done, no?","commit_id":"16e3eb21f2f4b7cf66e83caf7f9f02caccc892fb"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"493bdac7392ef9221d7197d42d20ada3eabf4ba3","unresolved":false,"context_lines":[{"line_number":137,"context_line":"   to ``active`` when upload to store is finished."},{"line_number":138,"context_line":""},{"line_number":139,"context_line":"   A future enhancement can add an API option or flag to expose ``pending``"},{"line_number":140,"context_line":"   locations (for example for operators who want to see import progress)."},{"line_number":141,"context_line":""},{"line_number":142,"context_line":"3. The default value is 1. This is for backward compatibility: same as"},{"line_number":143,"context_line":"sequential import today. If the operator tried a higher value and wants"}],"source_content_type":"text/x-rst","patch_set":9,"id":"86e7f6cb_13ac88d9","line":140,"in_reply_to":"cfdeafe5_cc97dee9","updated":"2026-05-15 06:50:54.000000000","message":"Ack, this sounds more useful. I will include this in the spec.","commit_id":"16e3eb21f2f4b7cf66e83caf7f9f02caccc892fb"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"02574f4b878573aad4f7ea2836e2e9ba21d6cd67","unresolved":true,"context_lines":[{"line_number":91,"context_line":"   Location Collection: When stores run in parallel, each task copies data"},{"line_number":92,"context_line":"   to its store and puts location info in one shared in-memory structure."},{"line_number":93,"context_line":"   Final location rows will be saved when Atomic Location Saving step runs to"},{"line_number":94,"context_line":"   avoid race conditions. We will also persists per-store"},{"line_number":95,"context_line":"   bookkeeping in the database while work is queued and uploading; see"},{"line_number":96,"context_line":"   ``Location status`` part below. Order of which store finishes first is not"},{"line_number":97,"context_line":"   important for correctness. When ``all_stores_must_succeed`` is True, image"}],"source_content_type":"text/x-rst","patch_set":10,"id":"d0a0e333_2a1bd23a","line":94,"range":{"start_line":94,"start_character":39,"end_line":94,"end_character":47},"updated":"2026-05-15 12:40:18.000000000","message":"persist","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"49157cff52d770bb31c479137bb0f9a13d1938b3","unresolved":false,"context_lines":[{"line_number":91,"context_line":"   Location Collection: When stores run in parallel, each task copies data"},{"line_number":92,"context_line":"   to its store and puts location info in one shared in-memory structure."},{"line_number":93,"context_line":"   Final location rows will be saved when Atomic Location Saving step runs to"},{"line_number":94,"context_line":"   avoid race conditions. We will also persists per-store"},{"line_number":95,"context_line":"   bookkeeping in the database while work is queued and uploading; see"},{"line_number":96,"context_line":"   ``Location status`` part below. Order of which store finishes first is not"},{"line_number":97,"context_line":"   important for correctness. When ``all_stores_must_succeed`` is True, image"}],"source_content_type":"text/x-rst","patch_set":10,"id":"adabf8ac_a3aeb187","line":94,"range":{"start_line":94,"start_character":39,"end_line":94,"end_character":47},"in_reply_to":"d0a0e333_2a1bd23a","updated":"2026-05-18 06:24:17.000000000","message":"Acknowledged","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"02574f4b878573aad4f7ea2836e2e9ba21d6cd67","unresolved":true,"context_lines":[{"line_number":96,"context_line":"   ``Location status`` part below. Order of which store finishes first is not"},{"line_number":97,"context_line":"   important for correctness. When ``all_stores_must_succeed`` is True, image"},{"line_number":98,"context_line":"   becomes ``active`` after Atomic Location Saving step. When"},{"line_number":99,"context_line":"   ``all_stores_must_succeed`` is False, image can become ``active`` as soon as"},{"line_number":100,"context_line":"   first store write is successful."},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"   Atomic Location Saving: A separate task runs to collect locations from the"}],"source_content_type":"text/x-rst","patch_set":10,"id":"0a72ecc9_0c0f8a7f","line":99,"range":{"start_line":99,"start_character":50,"end_line":99,"end_character":51},"updated":"2026-05-15 12:40:18.000000000","message":"\"can\" means optional in this context, which is good. I think it leaves you room to decide to do this right now or not ;)","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"49157cff52d770bb31c479137bb0f9a13d1938b3","unresolved":false,"context_lines":[{"line_number":96,"context_line":"   ``Location status`` part below. Order of which store finishes first is not"},{"line_number":97,"context_line":"   important for correctness. When ``all_stores_must_succeed`` is True, image"},{"line_number":98,"context_line":"   becomes ``active`` after Atomic Location Saving step. When"},{"line_number":99,"context_line":"   ``all_stores_must_succeed`` is False, image can become ``active`` as soon as"},{"line_number":100,"context_line":"   first store write is successful."},{"line_number":101,"context_line":""},{"line_number":102,"context_line":"   Atomic Location Saving: A separate task runs to collect locations from the"}],"source_content_type":"text/x-rst","patch_set":10,"id":"6c3f1e3d_962848ae","line":99,"range":{"start_line":99,"start_character":50,"end_line":99,"end_character":51},"in_reply_to":"0a72ecc9_0c0f8a7f","updated":"2026-05-18 06:24:17.000000000","message":"right, i will decide it on complexcity once I start the implementation.","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"02574f4b878573aad4f7ea2836e2e9ba21d6cd67","unresolved":true,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"   Failure behavior is still controlled by the existing"},{"line_number":125,"context_line":"   `all_stores_must_succeed` parameter. If it is True (default): when any"},{"line_number":126,"context_line":"   store import fails, the whole import fails at once. The image stays in"},{"line_number":127,"context_line":"   importing state. Revert must delete the image data on every store that"},{"line_number":128,"context_line":"   already had a successful write. This must be the same behavior as the"},{"line_number":129,"context_line":"   sequential import today. We cancel or wait until ongoing work stops,"}],"source_content_type":"text/x-rst","patch_set":10,"id":"915376d9_accbb7f4","line":126,"range":{"start_line":126,"start_character":23,"end_line":126,"end_character":53},"updated":"2026-05-15 12:40:18.000000000","message":"We need some way to signal the other uploaders to stop and abort as well, I guess. It would be bad if we start uploading to some expensive count-per-byte store, then fail to write to local/cheap storage with `-ENOSPC` and have no option but to wait for the other upload to finish just to delete it. That can be an implementation detail and discussed in the implementation patch, I just thought I\u0027d mention it here. Designing it to work that way from the start will be easier :)","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"49157cff52d770bb31c479137bb0f9a13d1938b3","unresolved":false,"context_lines":[{"line_number":123,"context_line":""},{"line_number":124,"context_line":"   Failure behavior is still controlled by the existing"},{"line_number":125,"context_line":"   `all_stores_must_succeed` parameter. If it is True (default): when any"},{"line_number":126,"context_line":"   store import fails, the whole import fails at once. The image stays in"},{"line_number":127,"context_line":"   importing state. Revert must delete the image data on every store that"},{"line_number":128,"context_line":"   already had a successful write. This must be the same behavior as the"},{"line_number":129,"context_line":"   sequential import today. We cancel or wait until ongoing work stops,"}],"source_content_type":"text/x-rst","patch_set":10,"id":"85e913af_5d2957db","line":126,"range":{"start_line":126,"start_character":23,"end_line":126,"end_character":53},"in_reply_to":"915376d9_accbb7f4","updated":"2026-05-18 06:24:17.000000000","message":"Acknowledged","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"02574f4b878573aad4f7ea2836e2e9ba21d6cd67","unresolved":true,"context_lines":[{"line_number":133,"context_line":"   If `all_stores_must_succeed` is False: the other jobs in the queue keep"},{"line_number":134,"context_line":"   running. Failed stores are written to `os_glance_failed_import`. Each"},{"line_number":135,"context_line":"   failed job must still delete partial or bad objects on that store, so only"},{"line_number":136,"context_line":"   clean locations go into the final save. As soon as first store write is"},{"line_number":137,"context_line":"   successful, image is set to ``active``. Remaining successful stores are"},{"line_number":138,"context_line":"   still reconciled into location rows."},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"   Location status in the database: With parallel import, if the worker"}],"source_content_type":"text/x-rst","patch_set":10,"id":"fe35fd49_3dac1374","line":137,"range":{"start_line":136,"start_character":43,"end_line":137,"end_character":41},"updated":"2026-05-15 12:40:18.000000000","message":"FWIW, I think this is desirable behavior, but I think it\u0027s fine to just specify that this behavior _can_ happen and save that for follow-up work if you want. Up to you, I just wanted to leave the possibility for this in the future.","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"49157cff52d770bb31c479137bb0f9a13d1938b3","unresolved":false,"context_lines":[{"line_number":133,"context_line":"   If `all_stores_must_succeed` is False: the other jobs in the queue keep"},{"line_number":134,"context_line":"   running. Failed stores are written to `os_glance_failed_import`. Each"},{"line_number":135,"context_line":"   failed job must still delete partial or bad objects on that store, so only"},{"line_number":136,"context_line":"   clean locations go into the final save. As soon as first store write is"},{"line_number":137,"context_line":"   successful, image is set to ``active``. Remaining successful stores are"},{"line_number":138,"context_line":"   still reconciled into location rows."},{"line_number":139,"context_line":""},{"line_number":140,"context_line":"   Location status in the database: With parallel import, if the worker"}],"source_content_type":"text/x-rst","patch_set":10,"id":"e8d5d9b0_34927980","line":137,"range":{"start_line":136,"start_character":43,"end_line":137,"end_character":41},"in_reply_to":"fe35fd49_3dac1374","updated":"2026-05-18 06:24:17.000000000","message":"Acknowledged","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"02574f4b878573aad4f7ea2836e2e9ba21d6cd67","unresolved":true,"context_lines":[{"line_number":158,"context_line":"   Optional: if we need one more step before we say location is fully"},{"line_number":159,"context_line":"   published (for example after checksum check across stores), we can add"},{"line_number":160,"context_line":"   status like ``uploaded`` meaning object is on backend and we know URI,"},{"line_number":161,"context_line":"   and ``active`` only after final step."},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"   Flow idea: for each store we register durable state (example: row with"},{"line_number":164,"context_line":"   ``pending``), put job in queue, wait until queue empty with bounded pool."}],"source_content_type":"text/x-rst","patch_set":10,"id":"7bbed9b8_03aa3cc2","line":161,"updated":"2026-05-15 12:40:18.000000000","message":"++","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"49157cff52d770bb31c479137bb0f9a13d1938b3","unresolved":false,"context_lines":[{"line_number":158,"context_line":"   Optional: if we need one more step before we say location is fully"},{"line_number":159,"context_line":"   published (for example after checksum check across stores), we can add"},{"line_number":160,"context_line":"   status like ``uploaded`` meaning object is on backend and we know URI,"},{"line_number":161,"context_line":"   and ``active`` only after final step."},{"line_number":162,"context_line":""},{"line_number":163,"context_line":"   Flow idea: for each store we register durable state (example: row with"},{"line_number":164,"context_line":"   ``pending``), put job in queue, wait until queue empty with bounded pool."}],"source_content_type":"text/x-rst","patch_set":10,"id":"a61f2a8a_196e1c71","line":161,"in_reply_to":"7bbed9b8_03aa3cc2","updated":"2026-05-18 06:24:17.000000000","message":"Done","commit_id":"c2bb4bff96bb7024bc7743357829bd48c16e9daf"}]}
