)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"60c07593f8723c0c2f6782f53aa1b7119be2ed45","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"d3fe5708_45cc15b2","updated":"2026-01-23 16:01:16.000000000","message":"Work in progress","commit_id":"ff1ca45b443436a145a0aa86503f06319ec80b2e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"b1f99f74304e76f76b7ca4db2d78d119a71f5c5b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"a9e47581_1a82b377","updated":"2026-01-23 18:42:42.000000000","message":"ah my review ci ignores change with workflow -1 no worries\nthat expalins why i did not trigger \nhttps://github.com/SeanMooney/ci-sean-mooney/blob/main/zuul.d/pipelines.yaml#L19","commit_id":"ff1ca45b443436a145a0aa86503f06319ec80b2e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"b2d293575d44f2918901f3a894e972e4509f92dc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"6de0a1e4_c51c88b6","updated":"2026-01-23 18:39:30.000000000","message":"teim-ci: manual","commit_id":"ff1ca45b443436a145a0aa86503f06319ec80b2e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"d28de198ce79e76be7d103109a1a8c3270dae52c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":1,"id":"d5337782_f4f2aa1a","updated":"2026-01-23 17:44:29.000000000","message":"teim-ci: manual","commit_id":"ff1ca45b443436a145a0aa86503f06319ec80b2e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"570867397758dcf96f858b35d785f96483eb8c5e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"19f11420_d6bb0e10","updated":"2026-01-27 14:09:35.000000000","message":"Couple things left I want to do but this is reviewable now","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"dfbfa8289b0bbb0e6aa711bcbac1086774c3b6a5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"5b4331ad_db31cd2f","updated":"2026-01-27 14:05:44.000000000","message":"OK this should pass basic testing now. I still want to check what,if any, functional coverage we have about this event delay mechanism. And also I would like to run some local devstack based scenarios to see if nothing fishy happens","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"8c9b4e89_3e337b13","updated":"2026-01-27 15:36:51.000000000","message":"a few comments but the overall direction seems correct to me.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3f1f8715902bb2b4c3b4f1fda7f7a69d53fade5b","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":5,"id":"98004097_24c52db6","in_reply_to":"5b4331ad_db31cd2f","updated":"2026-01-27 14:09:56.000000000","message":"I want this too","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7b2f84a17ff82c7a99976e1678e2d266f31a02d2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":5,"id":"792b80f8_6aeea121","in_reply_to":"98004097_24c52db6","updated":"2026-02-02 14:05:58.000000000","message":"Done","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"c3747eeb_b6628c36","updated":"2026-02-02 01:17:44.000000000","message":"this lgtm, some comment about tests name and one additional test. For shutdown, I am good on this.","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"8e6b0e35_9ec259f8","updated":"2026-02-01 04:46:27.000000000","message":"this looks good to me as a solution, ++ for investigating on it.\n\nMy -1 is for the shutdown behaviour (if needed we can discuss it in eventlet meeting) and rest other comments are trivial/non blocker which are about test names etc","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3e56256503c1a9ecead311dee0581338f1da8c2a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"8efb69b4_31c3295a","updated":"2026-02-02 12:48:27.000000000","message":"I need to do a cleanup still","commit_id":"0676e4d98569c13f024351a62d45bfe805d53359"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"fc71ef875013fed4f49028f77f65d8fbd1639438","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":13,"id":"52769282_11aa61e7","updated":"2026-02-03 14:26:49.000000000","message":"one slight debug removal and I\u0027m happy :-)","commit_id":"3fe3b3775a28cd596d2afa9c41751a68b8d945c8"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"0f7c03c3826306e49081d09813f90f00f73704d2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"9bd1caf1_ee918c78","updated":"2026-02-05 01:21:43.000000000","message":"just saw the Sean comment, let\u0027s merge it.","commit_id":"f16170695ccd0097cda47dd87e9c89bc8690122e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"2d447fbf9d0e04afb63f8fae8287f2f1a758359c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"e49ee53d_08916616","updated":"2026-02-05 12:37:25.000000000","message":"recheck ceph infra\n```\nDeleting cluster with fsid: 6d80e765-552d-4f20-a84b-72c045a11349\nTraceback (most recent call last):\n  File \"\u003cfrozen runpy\u003e\", line 198, in _run_module_as_main\n  File \"\u003cfrozen runpy\u003e\", line 88, in _run_code\n  File \"/usr/bin/cephadm/__main__.py\", line 5288, in \u003cmodule\u003e\n  File \"/usr/bin/cephadm/__main__.py\", line 5276, in main\n  File \"/usr/bin/cephadm/__main__.py\", line 2524, in _rollback\n  File \"/usr/bin/cephadm/__main__.py\", line 434, in _default_image\n  File \"/usr/bin/cephadm/__main__.py\", line 2773, in command_bootstrap\n  File \"/usr/bin/cephadm/__main__.py\", line 2277, in enable_cephadm_mgr_module\n  File \"/usr/bin/cephadm/__main__.py\", line 2709, in cli\n  File \"/usr/bin/cephadm/cephadmlib/container_types.py\", line 435, in run\n  File \"/usr/bin/cephadm/cephadmlib/call_wrappers.py\", line 307, in call_throws\nRuntimeError: Failed command: /usr/bin/podman run --rm --ipc\u003dhost --stop-signal\u003dSIGTERM --net\u003dhost --entrypoint /usr/bin/ceph --init -e CONTAINER_IMAGE\u003dquay.io/ceph/ceph:v20 -e NODE_NAME\u003dnp92fda6a88f1d4 -v /var/log/ceph/6d80e765-552d-4f20-a84b-72c045a11349:/var/log/ceph:z -v /tmp/ceph-tmp004sa5pq:/etc/ceph/ceph.client.admin.keyring:z -v /tmp/ceph-tmpe7zmt02u:/etc/ceph/ceph.conf:z quay.io/ceph/ceph:v20 orch set backend cephadm: Error ENOTSUP: Warning: due to ceph-mgr restart, some PG states may not be up to date\nModule \u0027orchestrator\u0027 is not enabled/loaded (required by command \u0027orch set backend\u0027): use `ceph mgr module enable orchestrator` to enable it\n```","commit_id":"f16170695ccd0097cda47dd87e9c89bc8690122e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e33695e690833dc9c34678eb46e078dae10aa985","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"58291d79_6f3472c2","updated":"2026-02-05 01:15:05.000000000","message":"recheck nova-next job fix is merged now","commit_id":"f16170695ccd0097cda47dd87e9c89bc8690122e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"600437737be5e68bf0231e97e87e50cc8a041be9","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"fe9cf9db_863e5c98","updated":"2026-02-05 09:50:10.000000000","message":"recheck post failure","commit_id":"f16170695ccd0097cda47dd87e9c89bc8690122e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"9af5b5f614c19e905b9c4bbfe9f4e066e3f0fc0c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"e9fc36fc_37801761","updated":"2026-02-04 19:34:00.000000000","message":"thanks for updates, lgtm. Waiting if Sean would like to check it (considering comments on libvirt event change) otherwise I will +W.","commit_id":"f16170695ccd0097cda47dd87e9c89bc8690122e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"1279a8c59585859b7bd71a9c00080a37c2c35d84","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":14,"id":"1a6c3ad5_d1c9f976","updated":"2026-02-04 20:54:20.000000000","message":"this is slightly different then i was expecting but i dont see anything that is obviously wrong however i have not spent enough time reviewing this to leave a +2 on a concurrence patch but i trust sylvian and gammn here and that gibi will fix it if it breaks something so if folks want to proceed with this they can without waitign for me to review futher\n\nthe intent is for this code to evenually mvoe to futureist so we will have an opertunity to refien it again if needed too.","commit_id":"f16170695ccd0097cda47dd87e9c89bc8690122e"}],"1q":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"f93dc5f652e28c3e8c3ecfa48ac872975456cb07","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":6,"id":"5dd374f5_21a57f60","updated":"2026-01-29 10:32:43.000000000","message":"I have no idea how this file was created and endedup in the commit","commit_id":"85c38537c45a5a809edf5a6983a4b869077a09d7"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d83764fa849cf1fb7e87d38170ca66a95d5d8cbe","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"589a38cc_fcc6be51","in_reply_to":"5dd374f5_21a57f60","updated":"2026-01-29 10:35:52.000000000","message":"Done","commit_id":"85c38537c45a5a809edf5a6983a4b869077a09d7"}],"nova/tests/unit/test_utils.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"60c07593f8723c0c2f6782f53aa1b7119be2ed45","unresolved":true,"context_lines":[{"line_number":2164,"context_line":"    \"waiting for task to finish\","},{"line_number":2165,"context_line":"    future,"},{"line_number":2166,"context_line":"     executor._executor.statistics)"},{"line_number":2167,"context_line":"        future.result()"},{"line_number":2168,"context_line":"        print(\"task finished\")"},{"line_number":2169,"context_line":"        # but our wrapper is in a shutdown state"},{"line_number":2170,"context_line":"        self.assertTrue(executor._shutdown_event.is_set())"}],"source_content_type":"text/x-python","patch_set":1,"id":"5c2b59ac_08b008bb","line":2167,"updated":"2026-01-23 16:01:16.000000000","message":"this hangs, and the real executor stats shows a failure. I need to figure out what fails and why.","commit_id":"ff1ca45b443436a145a0aa86503f06319ec80b2e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"2758e781586d8d6ffa49ce101728d245a1a1134d","unresolved":false,"context_lines":[{"line_number":2164,"context_line":"    \"waiting for task to finish\","},{"line_number":2165,"context_line":"    future,"},{"line_number":2166,"context_line":"     executor._executor.statistics)"},{"line_number":2167,"context_line":"        future.result()"},{"line_number":2168,"context_line":"        print(\"task finished\")"},{"line_number":2169,"context_line":"        # but our wrapper is in a shutdown state"},{"line_number":2170,"context_line":"        self.assertTrue(executor._shutdown_event.is_set())"}],"source_content_type":"text/x-python","patch_set":1,"id":"a30865bc_42bda263","line":2167,"in_reply_to":"5c2b59ac_08b008bb","updated":"2026-01-24 20:43:09.000000000","message":"Done","commit_id":"ff1ca45b443436a145a0aa86503f06319ec80b2e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":true,"context_lines":[{"line_number":2200,"context_line":"        self.assertFalse(task2_started.is_set())"},{"line_number":2201,"context_line":"        self.assertTrue(future2.cancelled())"},{"line_number":2202,"context_line":""},{"line_number":2203,"context_line":"    def test_unused_shutdown(self):"},{"line_number":2204,"context_line":"        executor \u003d utils.StaticallyDelayingCancellableTaskExecutorWrapper("},{"line_number":2205,"context_line":"            0.1, utils._get_default_executor())"},{"line_number":2206,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"19527aee_ffc07512","line":2203,"range":{"start_line":2203,"start_character":13,"end_line":2203,"end_character":28},"updated":"2026-02-01 04:46:27.000000000","message":"maybe test_instantaneous_shutdown","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3e56256503c1a9ecead311dee0581338f1da8c2a","unresolved":false,"context_lines":[{"line_number":2200,"context_line":"        self.assertFalse(task2_started.is_set())"},{"line_number":2201,"context_line":"        self.assertTrue(future2.cancelled())"},{"line_number":2202,"context_line":""},{"line_number":2203,"context_line":"    def test_unused_shutdown(self):"},{"line_number":2204,"context_line":"        executor \u003d utils.StaticallyDelayingCancellableTaskExecutorWrapper("},{"line_number":2205,"context_line":"            0.1, utils._get_default_executor())"},{"line_number":2206,"context_line":""}],"source_content_type":"text/x-python","patch_set":9,"id":"bb608d7f_e457ef68","line":2203,"range":{"start_line":2203,"start_character":13,"end_line":2203,"end_character":28},"in_reply_to":"19527aee_ffc07512","updated":"2026-02-02 12:48:27.000000000","message":"Done","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":true,"context_lines":[{"line_number":2232,"context_line":"        self.assertEqual("},{"line_number":2233,"context_line":"            \"Cannot schedule new tasks after being shutdown\", str(exc))"},{"line_number":2234,"context_line":""},{"line_number":2235,"context_line":"    def test_submit_while_shutting_down(self):"},{"line_number":2236,"context_line":"        task_started \u003d threading.Event()"},{"line_number":2237,"context_line":""},{"line_number":2238,"context_line":"        def task():"}],"source_content_type":"text/x-python","patch_set":9,"id":"5917d670_042711c9","line":2235,"range":{"start_line":2235,"start_character":8,"end_line":2235,"end_character":39},"updated":"2026-02-01 04:46:27.000000000","message":"test_submit_while_shutting_down_rejected","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3e56256503c1a9ecead311dee0581338f1da8c2a","unresolved":false,"context_lines":[{"line_number":2232,"context_line":"        self.assertEqual("},{"line_number":2233,"context_line":"            \"Cannot schedule new tasks after being shutdown\", str(exc))"},{"line_number":2234,"context_line":""},{"line_number":2235,"context_line":"    def test_submit_while_shutting_down(self):"},{"line_number":2236,"context_line":"        task_started \u003d threading.Event()"},{"line_number":2237,"context_line":""},{"line_number":2238,"context_line":"        def task():"}],"source_content_type":"text/x-python","patch_set":9,"id":"8bbb6952_4a9c174f","line":2235,"range":{"start_line":2235,"start_character":8,"end_line":2235,"end_character":39},"in_reply_to":"5917d670_042711c9","updated":"2026-02-02 12:48:27.000000000","message":"Done","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":true,"context_lines":[{"line_number":2256,"context_line":"        self.assertEqual("},{"line_number":2257,"context_line":"            \"Cannot schedule new tasks after being shutdown\", str(exc))"},{"line_number":2258,"context_line":""},{"line_number":2259,"context_line":"    def test_used_but_empty_shutdown(self):"},{"line_number":2260,"context_line":"        executor \u003d utils.StaticallyDelayingCancellableTaskExecutorWrapper("},{"line_number":2261,"context_line":"            0.01, utils._get_default_executor())"},{"line_number":2262,"context_line":"        self.addCleanup(executor.shutdown)"}],"source_content_type":"text/x-python","patch_set":9,"id":"6b284f05_b85a746d","line":2259,"range":{"start_line":2259,"start_character":8,"end_line":2259,"end_character":36},"updated":"2026-02-01 04:46:27.000000000","message":"maybe test_shutdown_wait_to_finish_tasks","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3e56256503c1a9ecead311dee0581338f1da8c2a","unresolved":false,"context_lines":[{"line_number":2256,"context_line":"        self.assertEqual("},{"line_number":2257,"context_line":"            \"Cannot schedule new tasks after being shutdown\", str(exc))"},{"line_number":2258,"context_line":""},{"line_number":2259,"context_line":"    def test_used_but_empty_shutdown(self):"},{"line_number":2260,"context_line":"        executor \u003d utils.StaticallyDelayingCancellableTaskExecutorWrapper("},{"line_number":2261,"context_line":"            0.01, utils._get_default_executor())"},{"line_number":2262,"context_line":"        self.addCleanup(executor.shutdown)"}],"source_content_type":"text/x-python","patch_set":9,"id":"a513286e_19093219","line":2259,"range":{"start_line":2259,"start_character":8,"end_line":2259,"end_character":36},"in_reply_to":"6b284f05_b85a746d","updated":"2026-02-02 12:48:27.000000000","message":"here there is not task to wait for as the single task execution is finished before the shutdown is requested","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":true,"context_lines":[{"line_number":2273,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2274,"context_line":"        self.assertFalse(executor.is_alive)"},{"line_number":2275,"context_line":""},{"line_number":2276,"context_line":"    def test_non_empty_shutdown(self):"},{"line_number":2277,"context_line":"        task_started \u003d threading.Event()"},{"line_number":2278,"context_line":""},{"line_number":2279,"context_line":"        def task():"}],"source_content_type":"text/x-python","patch_set":9,"id":"1d60a16e_5e6271bf","line":2276,"range":{"start_line":2276,"start_character":8,"end_line":2276,"end_character":31},"updated":"2026-02-02 01:17:44.000000000","message":"maybe test_non_wait_shutdown_still_finish_submitted_tasks","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3e56256503c1a9ecead311dee0581338f1da8c2a","unresolved":false,"context_lines":[{"line_number":2273,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2274,"context_line":"        self.assertFalse(executor.is_alive)"},{"line_number":2275,"context_line":""},{"line_number":2276,"context_line":"    def test_non_empty_shutdown(self):"},{"line_number":2277,"context_line":"        task_started \u003d threading.Event()"},{"line_number":2278,"context_line":""},{"line_number":2279,"context_line":"        def task():"}],"source_content_type":"text/x-python","patch_set":9,"id":"a2019115_cb01fe90","line":2276,"range":{"start_line":2276,"start_character":8,"end_line":2276,"end_character":31},"in_reply_to":"1d60a16e_5e6271bf","updated":"2026-02-02 12:48:27.000000000","message":"Done","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":true,"context_lines":[{"line_number":2303,"context_line":"        self.assertFalse(task_started.is_set())"},{"line_number":2304,"context_line":"        # and it is not cancelled"},{"line_number":2305,"context_line":"        self.assertFalse(future.cancelled())"},{"line_number":2306,"context_line":"        # and eventually executed"},{"line_number":2307,"context_line":"        self.assertEqual(42, future.result())"},{"line_number":2308,"context_line":"        # and eventually the executor is terminated. This also covers the case"},{"line_number":2309,"context_line":"        # when multiple shutdown call is made to the same executor."},{"line_number":2310,"context_line":"        executor.shutdown(wait\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":9,"id":"c6d60112_35a8d55c","line":2307,"range":{"start_line":2306,"start_character":0,"end_line":2307,"end_character":45},"updated":"2026-02-01 04:46:27.000000000","message":"in this case where shutdown is initiated then task should be rejected before submiting to actual executor. I commented about this behavior in utils file and if we agree on that, this and further tests can be modified.","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":false,"context_lines":[{"line_number":2303,"context_line":"        self.assertFalse(task_started.is_set())"},{"line_number":2304,"context_line":"        # and it is not cancelled"},{"line_number":2305,"context_line":"        self.assertFalse(future.cancelled())"},{"line_number":2306,"context_line":"        # and eventually executed"},{"line_number":2307,"context_line":"        self.assertEqual(42, future.result())"},{"line_number":2308,"context_line":"        # and eventually the executor is terminated. This also covers the case"},{"line_number":2309,"context_line":"        # when multiple shutdown call is made to the same executor."},{"line_number":2310,"context_line":"        executor.shutdown(wait\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":9,"id":"d8f9e95a_2b8c4bcc","line":2307,"range":{"start_line":2306,"start_character":0,"end_line":2307,"end_character":45},"in_reply_to":"c6d60112_35a8d55c","updated":"2026-02-02 01:17:44.000000000","message":"ignore this, I commented about it in utils file","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":true,"context_lines":[{"line_number":2311,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2312,"context_line":"        self.assertFalse(executor.is_alive)"},{"line_number":2313,"context_line":""},{"line_number":2314,"context_line":"    def test_non_empty_shutdown_wait_multiple(self):"},{"line_number":2315,"context_line":"        task1_started \u003d threading.Event()"},{"line_number":2316,"context_line":""},{"line_number":2317,"context_line":"        def task1():"}],"source_content_type":"text/x-python","patch_set":9,"id":"6520ba8c_80be25a4","line":2314,"range":{"start_line":2314,"start_character":8,"end_line":2314,"end_character":45},"updated":"2026-02-02 01:17:44.000000000","message":"test_shutdown_wait_to_finish_multiple_submitted_tasks","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3e56256503c1a9ecead311dee0581338f1da8c2a","unresolved":false,"context_lines":[{"line_number":2311,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2312,"context_line":"        self.assertFalse(executor.is_alive)"},{"line_number":2313,"context_line":""},{"line_number":2314,"context_line":"    def test_non_empty_shutdown_wait_multiple(self):"},{"line_number":2315,"context_line":"        task1_started \u003d threading.Event()"},{"line_number":2316,"context_line":""},{"line_number":2317,"context_line":"        def task1():"}],"source_content_type":"text/x-python","patch_set":9,"id":"66de7b36_9e289857","line":2314,"range":{"start_line":2314,"start_character":8,"end_line":2314,"end_character":45},"in_reply_to":"6520ba8c_80be25a4","updated":"2026-02-02 12:48:27.000000000","message":"Done","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":true,"context_lines":[{"line_number":2355,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2356,"context_line":"        self.assertFalse(executor.is_alive)"},{"line_number":2357,"context_line":""},{"line_number":2358,"context_line":"    def test_non_empty_shutdown_wait(self):"},{"line_number":2359,"context_line":"        task_started \u003d threading.Event()"},{"line_number":2360,"context_line":""},{"line_number":2361,"context_line":"        def task():"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a3f8541_9ce087f8","line":2358,"range":{"start_line":2358,"start_character":8,"end_line":2358,"end_character":36},"updated":"2026-02-02 01:17:44.000000000","message":"test_shutdown_with_wait_finish_submitted_tasks","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3e56256503c1a9ecead311dee0581338f1da8c2a","unresolved":false,"context_lines":[{"line_number":2355,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2356,"context_line":"        self.assertFalse(executor.is_alive)"},{"line_number":2357,"context_line":""},{"line_number":2358,"context_line":"    def test_non_empty_shutdown_wait(self):"},{"line_number":2359,"context_line":"        task_started \u003d threading.Event()"},{"line_number":2360,"context_line":""},{"line_number":2361,"context_line":"        def task():"}],"source_content_type":"text/x-python","patch_set":9,"id":"8c41e637_cbd824d9","line":2358,"range":{"start_line":2358,"start_character":8,"end_line":2358,"end_character":36},"in_reply_to":"9a3f8541_9ce087f8","updated":"2026-02-02 12:48:27.000000000","message":"Done","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":true,"context_lines":[{"line_number":2384,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2385,"context_line":"        self.assertFalse(executor.is_alive)"},{"line_number":2386,"context_line":""},{"line_number":2387,"context_line":"    def test_non_empty_shutdown_wait_cancel(self):"},{"line_number":2388,"context_line":"        task_started \u003d threading.Event()"},{"line_number":2389,"context_line":""},{"line_number":2390,"context_line":"        def task():"}],"source_content_type":"text/x-python","patch_set":9,"id":"dafb9bd6_27e6c8f3","line":2387,"range":{"start_line":2387,"start_character":8,"end_line":2387,"end_character":43},"updated":"2026-02-02 01:17:44.000000000","message":"test_shutdown_does_not_wait_for_canceled_tasks","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3e56256503c1a9ecead311dee0581338f1da8c2a","unresolved":false,"context_lines":[{"line_number":2384,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2385,"context_line":"        self.assertFalse(executor.is_alive)"},{"line_number":2386,"context_line":""},{"line_number":2387,"context_line":"    def test_non_empty_shutdown_wait_cancel(self):"},{"line_number":2388,"context_line":"        task_started \u003d threading.Event()"},{"line_number":2389,"context_line":""},{"line_number":2390,"context_line":"        def task():"}],"source_content_type":"text/x-python","patch_set":9,"id":"f23b367a_b9ad82e9","line":2387,"range":{"start_line":2387,"start_character":8,"end_line":2387,"end_character":43},"in_reply_to":"dafb9bd6_27e6c8f3","updated":"2026-02-02 12:48:27.000000000","message":"Done","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":true,"context_lines":[{"line_number":2411,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2412,"context_line":"        self.assertFalse(executor.is_alive)"},{"line_number":2413,"context_line":""},{"line_number":2414,"context_line":"    def test_non_empty_shutdown_wait_cancel_multiple(self):"},{"line_number":2415,"context_line":"        task1_started \u003d threading.Event()"},{"line_number":2416,"context_line":""},{"line_number":2417,"context_line":"        def task1():"}],"source_content_type":"text/x-python","patch_set":9,"id":"a0c78ca8_55b3c434","line":2414,"range":{"start_line":2414,"start_character":8,"end_line":2414,"end_character":52},"updated":"2026-02-02 01:17:44.000000000","message":"test_shutdown_does_not_wait_for_canceled_multiple_tasks","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"3e56256503c1a9ecead311dee0581338f1da8c2a","unresolved":false,"context_lines":[{"line_number":2411,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2412,"context_line":"        self.assertFalse(executor.is_alive)"},{"line_number":2413,"context_line":""},{"line_number":2414,"context_line":"    def test_non_empty_shutdown_wait_cancel_multiple(self):"},{"line_number":2415,"context_line":"        task1_started \u003d threading.Event()"},{"line_number":2416,"context_line":""},{"line_number":2417,"context_line":"        def task1():"}],"source_content_type":"text/x-python","patch_set":9,"id":"544ff089_991f502a","line":2414,"range":{"start_line":2414,"start_character":8,"end_line":2414,"end_character":52},"in_reply_to":"a0c78ca8_55b3c434","updated":"2026-02-02 12:48:27.000000000","message":"Done","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":true,"context_lines":[{"line_number":2458,"context_line":"        # and our wrapper is in a shutdown state"},{"line_number":2459,"context_line":"        self.assertTrue(executor._shutdown)"},{"line_number":2460,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2461,"context_line":"        self.assertFalse(executor.is_alive)"}],"source_content_type":"text/x-python","patch_set":9,"id":"51a0294a_c6a14592","line":2461,"range":{"start_line":2461,"start_character":42,"end_line":2461,"end_character":43},"updated":"2026-02-02 01:17:44.000000000","message":"can we add a another test here that if tasks are submitted after shutdown() then those will be rejected.","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7b2f84a17ff82c7a99976e1678e2d266f31a02d2","unresolved":false,"context_lines":[{"line_number":2458,"context_line":"        # and our wrapper is in a shutdown state"},{"line_number":2459,"context_line":"        self.assertTrue(executor._shutdown)"},{"line_number":2460,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2461,"context_line":"        self.assertFalse(executor.is_alive)"}],"source_content_type":"text/x-python","patch_set":9,"id":"c1c4d0b2_3c1a4bc9","line":2461,"range":{"start_line":2461,"start_character":42,"end_line":2461,"end_character":43},"in_reply_to":"51a0294a_c6a14592","updated":"2026-02-02 14:05:58.000000000","message":"we have test_submit_after_shutdown_rejected that covers it","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"bcfb6fc9793b9c840386fcf070f4dabbe6eb6b2e","unresolved":false,"context_lines":[{"line_number":2458,"context_line":"        # and our wrapper is in a shutdown state"},{"line_number":2459,"context_line":"        self.assertTrue(executor._shutdown)"},{"line_number":2460,"context_line":"        self.assertTrue(executor._queue.empty())"},{"line_number":2461,"context_line":"        self.assertFalse(executor.is_alive)"}],"source_content_type":"text/x-python","patch_set":9,"id":"0e9a64d5_3f131862","line":2461,"range":{"start_line":2461,"start_character":42,"end_line":2461,"end_character":43},"in_reply_to":"c1c4d0b2_3c1a4bc9","updated":"2026-02-02 18:51:29.000000000","message":"i see, I overlooked that.","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"fc71ef875013fed4f49028f77f65d8fbd1639438","unresolved":true,"context_lines":[{"line_number":2482,"context_line":"        # task will be executed."},{"line_number":2483,"context_line":"        future1.cancel()"},{"line_number":2484,"context_line":"        future2.cancel()"},{"line_number":2485,"context_line":"        print(\"test cancelled tasks\", future1, future2)"},{"line_number":2486,"context_line":"        executor.shutdown(wait\u003dTrue)"},{"line_number":2487,"context_line":""},{"line_number":2488,"context_line":"        self.assertFalse(task1_started.is_set())"}],"source_content_type":"text/x-python","patch_set":13,"id":"51e242b8_3edf895e","line":2485,"updated":"2026-02-03 14:26:49.000000000","message":"missing debug print removal I guess 😜","commit_id":"3fe3b3775a28cd596d2afa9c41751a68b8d945c8"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"dae5e22633e0ef1b5628eccc85e96f32552ac69c","unresolved":false,"context_lines":[{"line_number":2482,"context_line":"        # task will be executed."},{"line_number":2483,"context_line":"        future1.cancel()"},{"line_number":2484,"context_line":"        future2.cancel()"},{"line_number":2485,"context_line":"        print(\"test cancelled tasks\", future1, future2)"},{"line_number":2486,"context_line":"        executor.shutdown(wait\u003dTrue)"},{"line_number":2487,"context_line":""},{"line_number":2488,"context_line":"        self.assertFalse(task1_started.is_set())"}],"source_content_type":"text/x-python","patch_set":13,"id":"59935805_221d6388","line":2485,"in_reply_to":"51e242b8_3edf895e","updated":"2026-02-04 11:15:35.000000000","message":"Done","commit_id":"3fe3b3775a28cd596d2afa9c41751a68b8d945c8"}],"nova/utils.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"60c07593f8723c0c2f6782f53aa1b7119be2ed45","unresolved":true,"context_lines":[{"line_number":1396,"context_line":"        return tpool.Proxy(target, autowrap\u003dautowrap)"},{"line_number":1397,"context_line":""},{"line_number":1398,"context_line":""},{"line_number":1399,"context_line":"class StaticallyDelayingCancellableTaskExecutorWrapper(futures.Executor):"},{"line_number":1400,"context_line":"    \"\"\"Executor wrapper that submit work to another executor but delays each"},{"line_number":1401,"context_line":"    task\u0027s submission with a statically defined delay and supports cancelling"},{"line_number":1402,"context_line":"    the task during such delay."}],"source_content_type":"text/x-python","patch_set":1,"id":"5b8211e3_909d86a2","line":1399,"updated":"2026-01-23 16:01:16.000000000","message":"very enterprisy name. Bikeshed it!","commit_id":"ff1ca45b443436a145a0aa86503f06319ec80b2e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"b2d293575d44f2918901f3a894e972e4509f92dc","unresolved":true,"context_lines":[{"line_number":1396,"context_line":"        return tpool.Proxy(target, autowrap\u003dautowrap)"},{"line_number":1397,"context_line":""},{"line_number":1398,"context_line":""},{"line_number":1399,"context_line":"class StaticallyDelayingCancellableTaskExecutorWrapper(futures.Executor):"},{"line_number":1400,"context_line":"    \"\"\"Executor wrapper that submit work to another executor but delays each"},{"line_number":1401,"context_line":"    task\u0027s submission with a statically defined delay and supports cancelling"},{"line_number":1402,"context_line":"    the task during such delay."}],"source_content_type":"text/x-python","patch_set":1,"id":"c1f629e7_0087194b","line":1399,"in_reply_to":"5b8211e3_909d86a2","updated":"2026-01-23 18:39:30.000000000","message":"PerpetuallyPostponingPuntablePhuntorPerformerProcesor :)\n\nthis is not quite what i was describing but its somewhat cloase and i see you adde canceltion","commit_id":"ff1ca45b443436a145a0aa86503f06319ec80b2e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"6b606dd49bcc340b7c68bae6c8a85809f79ad9d7","unresolved":true,"context_lines":[{"line_number":1396,"context_line":"        return tpool.Proxy(target, autowrap\u003dautowrap)"},{"line_number":1397,"context_line":""},{"line_number":1398,"context_line":""},{"line_number":1399,"context_line":"class StaticallyDelayingCancellableTaskExecutorWrapper(futures.Executor):"},{"line_number":1400,"context_line":"    \"\"\"Executor wrapper that submit work to another executor but delays each"},{"line_number":1401,"context_line":"    task\u0027s submission with a statically defined delay and supports cancelling"},{"line_number":1402,"context_line":"    the task during such delay."}],"source_content_type":"text/x-python","patch_set":1,"id":"e39d78e3_1fbd1ea9","line":1399,"in_reply_to":"c1f629e7_0087194b","updated":"2026-01-23 18:40:36.000000000","message":"im not sure ill have time today to review this propely but ill take a look at  it on monday","commit_id":"ff1ca45b443436a145a0aa86503f06319ec80b2e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"cb31fc5bd2110a11f37ba4ec2e36b5777302c81d","unresolved":true,"context_lines":[{"line_number":1521,"context_line":""},{"line_number":1522,"context_line":"            deadline \u003d time.monotonic() + self._delay"},{"line_number":1523,"context_line":"            # create a new future to return to the caller so it can wait for"},{"line_number":1524,"context_line":"            # the result of cancel the task while it is delayed"},{"line_number":1525,"context_line":"            # The _run() logic will makes sure that the result of the task"},{"line_number":1526,"context_line":"            # will be set on this future when available."},{"line_number":1527,"context_line":"            future \u003d futurist.Future()"}],"source_content_type":"text/x-python","patch_set":2,"id":"91b9d7ac_30600a12","line":1524,"range":{"start_line":1524,"start_character":25,"end_line":1524,"end_character":27},"updated":"2026-01-25 20:02:15.000000000","message":"or","commit_id":"db8cf2fca4cfcdd489be3f6655d99b729fbea7f0"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7b2f84a17ff82c7a99976e1678e2d266f31a02d2","unresolved":false,"context_lines":[{"line_number":1521,"context_line":""},{"line_number":1522,"context_line":"            deadline \u003d time.monotonic() + self._delay"},{"line_number":1523,"context_line":"            # create a new future to return to the caller so it can wait for"},{"line_number":1524,"context_line":"            # the result of cancel the task while it is delayed"},{"line_number":1525,"context_line":"            # The _run() logic will makes sure that the result of the task"},{"line_number":1526,"context_line":"            # will be set on this future when available."},{"line_number":1527,"context_line":"            future \u003d futurist.Future()"}],"source_content_type":"text/x-python","patch_set":2,"id":"b9b62cfb_443fcbec","line":1524,"range":{"start_line":1524,"start_character":25,"end_line":1524,"end_character":27},"in_reply_to":"91b9d7ac_30600a12","updated":"2026-02-02 14:05:58.000000000","message":"Done","commit_id":"db8cf2fca4cfcdd489be3f6655d99b729fbea7f0"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"570867397758dcf96f858b35d785f96483eb8c5e","unresolved":true,"context_lines":[{"line_number":579,"context_line":"    return spawn_on(_get_default_executor(), func, *args, **kwargs)"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":""},{"line_number":582,"context_line":"def spawn_after(seconds, func, *args, **kwargs) -\u003e futurist.Future:"},{"line_number":583,"context_line":"    \"\"\"Executing the function asynchronously after the given time.\"\"\""},{"line_number":584,"context_line":""},{"line_number":585,"context_line":"    def delayed(*args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":5,"id":"b2bff5cc_7ebf677e","line":582,"updated":"2026-01-27 14:09:35.000000000","message":"This can be removed as it is unused and it is a very naive implementation (non cancellable, and each delay hold a full thread)","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7b2f84a17ff82c7a99976e1678e2d266f31a02d2","unresolved":false,"context_lines":[{"line_number":579,"context_line":"    return spawn_on(_get_default_executor(), func, *args, **kwargs)"},{"line_number":580,"context_line":""},{"line_number":581,"context_line":""},{"line_number":582,"context_line":"def spawn_after(seconds, func, *args, **kwargs) -\u003e futurist.Future:"},{"line_number":583,"context_line":"    \"\"\"Executing the function asynchronously after the given time.\"\"\""},{"line_number":584,"context_line":""},{"line_number":585,"context_line":"    def delayed(*args, **kwargs):"}],"source_content_type":"text/x-python","patch_set":5,"id":"f13c9120_d473c71b","line":582,"in_reply_to":"b2bff5cc_7ebf677e","updated":"2026-02-02 14:05:58.000000000","message":"Done","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":true,"context_lines":[{"line_number":1405,"context_line":"    concurrency mode used. See"},{"line_number":1406,"context_line":"    https://docs.python.org/3.12/library/concurrent.futures.html#concurrent.futures.Future.cancel"},{"line_number":1407,"context_line":""},{"line_number":1408,"context_line":"    Note that shutting down the wrapper only shuts down its own scheduler thead"},{"line_number":1409,"context_line":"    but does not shut down the real executor that is passed in __init__."},{"line_number":1410,"context_line":""},{"line_number":1411,"context_line":"    Note that this class does not support a different delay length for"}],"source_content_type":"text/x-python","patch_set":5,"id":"af83bee4_dd3a6acb","line":1408,"range":{"start_line":1408,"start_character":74,"end_line":1408,"end_character":79},"updated":"2026-01-27 15:36:51.000000000","message":"nit: thread","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"fa99811e6a10884a7feee14c2f474d126d9143e6","unresolved":false,"context_lines":[{"line_number":1405,"context_line":"    concurrency mode used. See"},{"line_number":1406,"context_line":"    https://docs.python.org/3.12/library/concurrent.futures.html#concurrent.futures.Future.cancel"},{"line_number":1407,"context_line":""},{"line_number":1408,"context_line":"    Note that shutting down the wrapper only shuts down its own scheduler thead"},{"line_number":1409,"context_line":"    but does not shut down the real executor that is passed in __init__."},{"line_number":1410,"context_line":""},{"line_number":1411,"context_line":"    Note that this class does not support a different delay length for"}],"source_content_type":"text/x-python","patch_set":5,"id":"ab43b34b_7029063e","line":1408,"range":{"start_line":1408,"start_character":74,"end_line":1408,"end_character":79},"in_reply_to":"af83bee4_dd3a6acb","updated":"2026-01-29 10:31:27.000000000","message":"Done","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"570867397758dcf96f858b35d785f96483eb8c5e","unresolved":true,"context_lines":[{"line_number":1413,"context_line":"    \"\"\""},{"line_number":1414,"context_line":""},{"line_number":1415,"context_line":"    # TODO(gibi): rearrange the mypy patch and then add exact type for"},{"line_number":1416,"context_line":"    # the executor param, that it only supports futurist executors"},{"line_number":1417,"context_line":"    def __init__(self, delay, executor):"},{"line_number":1418,"context_line":"        \"\"\"Initialize the wrapper"},{"line_number":1419,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"f148d62d_e68afcc5","line":1416,"updated":"2026-01-27 14:09:35.000000000","message":"Yepp I would like to do that too now","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"931e4e9b5ebac2a19f63e2cc20d2e92e2ea98370","unresolved":false,"context_lines":[{"line_number":1413,"context_line":"    \"\"\""},{"line_number":1414,"context_line":""},{"line_number":1415,"context_line":"    # TODO(gibi): rearrange the mypy patch and then add exact type for"},{"line_number":1416,"context_line":"    # the executor param, that it only supports futurist executors"},{"line_number":1417,"context_line":"    def __init__(self, delay, executor):"},{"line_number":1418,"context_line":"        \"\"\"Initialize the wrapper"},{"line_number":1419,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"4f27ab02_c7c63b23","line":1416,"in_reply_to":"f148d62d_e68afcc5","updated":"2026-01-29 10:56:12.000000000","message":"Done","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":true,"context_lines":[{"line_number":1427,"context_line":"        self._delay \u003d delay"},{"line_number":1428,"context_line":"        self._shutdown_lock \u003d threading.Lock()"},{"line_number":1429,"context_line":"        self._shutdown \u003d False"},{"line_number":1430,"context_line":"        self._poison \u003d object()"},{"line_number":1431,"context_line":"        # We are intentionally not running our _run() in the executor"},{"line_number":1432,"context_line":"        # as we cannot assume that the executor has more than one worker"},{"line_number":1433,"context_line":"        # and our logic never finishes so it would consume one worker"}],"source_content_type":"text/x-python","patch_set":5,"id":"202aa7af_189f9ce3","line":1430,"updated":"2026-01-27 15:36:51.000000000","message":"bikeshed: that\u0027s a sentinel, it took me a few brain cycles to get its purpose, so a naming convention could be `self._poison_sentinel` but I don\u0027t want to argue about it.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d5e54548cc30af0ba4ea64fbe12e6d13d598341e","unresolved":true,"context_lines":[{"line_number":1427,"context_line":"        self._delay \u003d delay"},{"line_number":1428,"context_line":"        self._shutdown_lock \u003d threading.Lock()"},{"line_number":1429,"context_line":"        self._shutdown \u003d False"},{"line_number":1430,"context_line":"        self._poison \u003d object()"},{"line_number":1431,"context_line":"        # We are intentionally not running our _run() in the executor"},{"line_number":1432,"context_line":"        # as we cannot assume that the executor has more than one worker"},{"line_number":1433,"context_line":"        # and our logic never finishes so it would consume one worker"}],"source_content_type":"text/x-python","patch_set":5,"id":"a02aa9ae_7d72c22d","line":1430,"in_reply_to":"202aa7af_189f9ce3","updated":"2026-01-27 18:47:33.000000000","message":"I can name it to sentinel. First I named it tombstone but it is not that as it does not represent an object existed in the past, then I named it poison as when the thread takes this pill it dies. But yeah sentinel is even better.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"fa99811e6a10884a7feee14c2f474d126d9143e6","unresolved":false,"context_lines":[{"line_number":1427,"context_line":"        self._delay \u003d delay"},{"line_number":1428,"context_line":"        self._shutdown_lock \u003d threading.Lock()"},{"line_number":1429,"context_line":"        self._shutdown \u003d False"},{"line_number":1430,"context_line":"        self._poison \u003d object()"},{"line_number":1431,"context_line":"        # We are intentionally not running our _run() in the executor"},{"line_number":1432,"context_line":"        # as we cannot assume that the executor has more than one worker"},{"line_number":1433,"context_line":"        # and our logic never finishes so it would consume one worker"}],"source_content_type":"text/x-python","patch_set":5,"id":"69917d1d_757873c3","line":1430,"in_reply_to":"a02aa9ae_7d72c22d","updated":"2026-01-29 10:31:27.000000000","message":"Done","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"570867397758dcf96f858b35d785f96483eb8c5e","unresolved":true,"context_lines":[{"line_number":1432,"context_line":"        # as we cannot assume that the executor has more than one worker"},{"line_number":1433,"context_line":"        # and our logic never finishes so it would consume one worker"},{"line_number":1434,"context_line":"        # constantly."},{"line_number":1435,"context_line":"        self._thread \u003d threading.Thread(target\u003dself._run)"},{"line_number":1436,"context_line":"        self._thread.daemon \u003d True"},{"line_number":1437,"context_line":"        self._thread.start()"},{"line_number":1438,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"7a2e838d_ece90adf","line":1435,"updated":"2026-01-27 14:09:35.000000000","message":"We need a way in our unit test to avoid leaking this running thread across the test cases within the same executor. Basically we need a fixture that can call shutdown() at the end of the test case.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"422778e09fed3a10b97b427c8afb1eb24c987754","unresolved":true,"context_lines":[{"line_number":1432,"context_line":"        # as we cannot assume that the executor has more than one worker"},{"line_number":1433,"context_line":"        # and our logic never finishes so it would consume one worker"},{"line_number":1434,"context_line":"        # constantly."},{"line_number":1435,"context_line":"        self._thread \u003d threading.Thread(target\u003dself._run)"},{"line_number":1436,"context_line":"        self._thread.daemon \u003d True"},{"line_number":1437,"context_line":"        self._thread.start()"},{"line_number":1438,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"b6154208_76242738","line":1435,"in_reply_to":"7a2e838d_ece90adf","updated":"2026-01-27 18:12:52.000000000","message":"OK we can do that in two ways. Try to catch all usage in a fixture and force the shutdown in cleanup. \nOR\nImplement the cleanup_host virt driver call for libvirt driver and shutdown the wrapper there specifically.\n\nI definitely want the second for graceful shutdown perspective. But I might need both for safety.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"eede063c59462269617fb20e5bbe12f4f75a69fe","unresolved":false,"context_lines":[{"line_number":1432,"context_line":"        # as we cannot assume that the executor has more than one worker"},{"line_number":1433,"context_line":"        # and our logic never finishes so it would consume one worker"},{"line_number":1434,"context_line":"        # constantly."},{"line_number":1435,"context_line":"        self._thread \u003d threading.Thread(target\u003dself._run)"},{"line_number":1436,"context_line":"        self._thread.daemon \u003d True"},{"line_number":1437,"context_line":"        self._thread.start()"},{"line_number":1438,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"5a5d0a1c_2db0b4b7","line":1435,"in_reply_to":"b6154208_76242738","updated":"2026-01-29 10:40:36.000000000","message":"I added both in the next patch","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":true,"context_lines":[{"line_number":1433,"context_line":"        # and our logic never finishes so it would consume one worker"},{"line_number":1434,"context_line":"        # constantly."},{"line_number":1435,"context_line":"        self._thread \u003d threading.Thread(target\u003dself._run)"},{"line_number":1436,"context_line":"        self._thread.daemon \u003d True"},{"line_number":1437,"context_line":"        self._thread.start()"},{"line_number":1438,"context_line":""},{"line_number":1439,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":5,"id":"f75ec916_8250c2d9","line":1436,"updated":"2026-01-27 15:36:51.000000000","message":"if that\u0027s a thread deamon, it will exit abruptely when we stop the compute service.\nI guess @gmaan@ghanshyammann.com needs to look at it for graceful shutdown then.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":false,"context_lines":[{"line_number":1433,"context_line":"        # and our logic never finishes so it would consume one worker"},{"line_number":1434,"context_line":"        # constantly."},{"line_number":1435,"context_line":"        self._thread \u003d threading.Thread(target\u003dself._run)"},{"line_number":1436,"context_line":"        self._thread.daemon \u003d True"},{"line_number":1437,"context_line":"        self._thread.start()"},{"line_number":1438,"context_line":""},{"line_number":1439,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":5,"id":"d1c8ac8e_afe31c34","line":1436,"in_reply_to":"1d075608_1a6a28f7","updated":"2026-02-01 04:46:27.000000000","message":"I think making it or not it as daemon is fine as we should be calling this wrapper shutdown during graceful shutdown.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"fa99811e6a10884a7feee14c2f474d126d9143e6","unresolved":true,"context_lines":[{"line_number":1433,"context_line":"        # and our logic never finishes so it would consume one worker"},{"line_number":1434,"context_line":"        # constantly."},{"line_number":1435,"context_line":"        self._thread \u003d threading.Thread(target\u003dself._run)"},{"line_number":1436,"context_line":"        self._thread.daemon \u003d True"},{"line_number":1437,"context_line":"        self._thread.start()"},{"line_number":1438,"context_line":""},{"line_number":1439,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":5,"id":"1d075608_1a6a28f7","line":1436,"in_reply_to":"edac075c_2b9f101f","updated":"2026-01-29 10:31:27.000000000","message":"Stopping this thread as compute service stop is handled by https://review.opendev.org/c/openstack/nova/+/975128","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d5e54548cc30af0ba4ea64fbe12e6d13d598341e","unresolved":true,"context_lines":[{"line_number":1433,"context_line":"        # and our logic never finishes so it would consume one worker"},{"line_number":1434,"context_line":"        # constantly."},{"line_number":1435,"context_line":"        self._thread \u003d threading.Thread(target\u003dself._run)"},{"line_number":1436,"context_line":"        self._thread.daemon \u003d True"},{"line_number":1437,"context_line":"        self._thread.start()"},{"line_number":1438,"context_line":""},{"line_number":1439,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":5,"id":"edac075c_2b9f101f","line":1436,"in_reply_to":"f75ec916_8250c2d9","updated":"2026-01-27 18:47:33.000000000","message":"yeah I realized I need to add virt driver cleanup_host to libvirt driver to do the shutdown cleanly at service.stop. I will add that. We can decide to not make it a daemon if we want as soon as we have shutdown called at service.stop","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"570867397758dcf96f858b35d785f96483eb8c5e","unresolved":true,"context_lines":[{"line_number":1444,"context_line":"        the caller can get the result or exception from the task."},{"line_number":1445,"context_line":"        \"\"\""},{"line_number":1446,"context_line":"        try:"},{"line_number":1447,"context_line":"            print(\"running task async\", fn)"},{"line_number":1448,"context_line":"            result \u003d fn(*args, **kwargs)"},{"line_number":1449,"context_line":"            print(\"task\u0027s result\", result)"},{"line_number":1450,"context_line":"            future.set_result(result)"}],"source_content_type":"text/x-python","patch_set":5,"id":"fecc8f91_b7fdb1f7","line":1447,"updated":"2026-01-27 14:09:35.000000000","message":"I will remove the printouts as soon as I finished with my local testing.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7b2f84a17ff82c7a99976e1678e2d266f31a02d2","unresolved":false,"context_lines":[{"line_number":1444,"context_line":"        the caller can get the result or exception from the task."},{"line_number":1445,"context_line":"        \"\"\""},{"line_number":1446,"context_line":"        try:"},{"line_number":1447,"context_line":"            print(\"running task async\", fn)"},{"line_number":1448,"context_line":"            result \u003d fn(*args, **kwargs)"},{"line_number":1449,"context_line":"            print(\"task\u0027s result\", result)"},{"line_number":1450,"context_line":"            future.set_result(result)"}],"source_content_type":"text/x-python","patch_set":5,"id":"882f0f6a_fff7cc4e","line":1447,"in_reply_to":"2c840883_6f1c6d2f","updated":"2026-02-02 14:05:58.000000000","message":"Done","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":true,"context_lines":[{"line_number":1444,"context_line":"        the caller can get the result or exception from the task."},{"line_number":1445,"context_line":"        \"\"\""},{"line_number":1446,"context_line":"        try:"},{"line_number":1447,"context_line":"            print(\"running task async\", fn)"},{"line_number":1448,"context_line":"            result \u003d fn(*args, **kwargs)"},{"line_number":1449,"context_line":"            print(\"task\u0027s result\", result)"},{"line_number":1450,"context_line":"            future.set_result(result)"}],"source_content_type":"text/x-python","patch_set":5,"id":"2c840883_6f1c6d2f","line":1447,"in_reply_to":"ab3a438a_4a2d167b","updated":"2026-02-01 04:46:27.000000000","message":"Istead of removeing, it is good to convert those print to LOG message as they can be useful for debugging. this and the below one.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":true,"context_lines":[{"line_number":1444,"context_line":"        the caller can get the result or exception from the task."},{"line_number":1445,"context_line":"        \"\"\""},{"line_number":1446,"context_line":"        try:"},{"line_number":1447,"context_line":"            print(\"running task async\", fn)"},{"line_number":1448,"context_line":"            result \u003d fn(*args, **kwargs)"},{"line_number":1449,"context_line":"            print(\"task\u0027s result\", result)"},{"line_number":1450,"context_line":"            future.set_result(result)"}],"source_content_type":"text/x-python","patch_set":5,"id":"ab3a438a_4a2d167b","line":1447,"in_reply_to":"fecc8f91_b7fdb1f7","updated":"2026-01-27 15:36:51.000000000","message":"Noted (obviously)","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":true,"context_lines":[{"line_number":1448,"context_line":"            result \u003d fn(*args, **kwargs)"},{"line_number":1449,"context_line":"            print(\"task\u0027s result\", result)"},{"line_number":1450,"context_line":"            future.set_result(result)"},{"line_number":1451,"context_line":"        except BaseException as e:"},{"line_number":1452,"context_line":"            future.set_exception(e)"},{"line_number":1453,"context_line":""},{"line_number":1454,"context_line":"        print(\"task finished\")"}],"source_content_type":"text/x-python","patch_set":5,"id":"e6be9861_ad281c8a","line":1451,"range":{"start_line":1451,"start_character":15,"end_line":1451,"end_character":28},"updated":"2026-01-27 15:36:51.000000000","message":"nit: I\u0027m not a big fan of exception catchalls but here I think we can\u0027t check a specific exception.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"fa99811e6a10884a7feee14c2f474d126d9143e6","unresolved":false,"context_lines":[{"line_number":1448,"context_line":"            result \u003d fn(*args, **kwargs)"},{"line_number":1449,"context_line":"            print(\"task\u0027s result\", result)"},{"line_number":1450,"context_line":"            future.set_result(result)"},{"line_number":1451,"context_line":"        except BaseException as e:"},{"line_number":1452,"context_line":"            future.set_exception(e)"},{"line_number":1453,"context_line":""},{"line_number":1454,"context_line":"        print(\"task finished\")"}],"source_content_type":"text/x-python","patch_set":5,"id":"5aaba8d2_d0464cc0","line":1451,"range":{"start_line":1451,"start_character":15,"end_line":1451,"end_character":28},"in_reply_to":"2a117c23_56b3c2ab","updated":"2026-01-29 10:31:27.000000000","message":"Acknowledged","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d5e54548cc30af0ba4ea64fbe12e6d13d598341e","unresolved":true,"context_lines":[{"line_number":1448,"context_line":"            result \u003d fn(*args, **kwargs)"},{"line_number":1449,"context_line":"            print(\"task\u0027s result\", result)"},{"line_number":1450,"context_line":"            future.set_result(result)"},{"line_number":1451,"context_line":"        except BaseException as e:"},{"line_number":1452,"context_line":"            future.set_exception(e)"},{"line_number":1453,"context_line":""},{"line_number":1454,"context_line":"        print(\"task finished\")"}],"source_content_type":"text/x-python","patch_set":5,"id":"2a117c23_56b3c2ab","line":1451,"range":{"start_line":1451,"start_character":15,"end_line":1451,"end_character":28},"in_reply_to":"e6be9861_ad281c8a","updated":"2026-01-27 18:47:33.000000000","message":"yeah we need to catch everything and pass it to the outer future that is held by our client","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":true,"context_lines":[{"line_number":1462,"context_line":"            if future is self._poison:"},{"line_number":1463,"context_line":"                # We are asked to terminate so exit the loop."},{"line_number":1464,"context_line":"                self._queue.task_done()"},{"line_number":1465,"context_line":"                print(\"got poision, returning\")"},{"line_number":1466,"context_line":"                return"},{"line_number":1467,"context_line":""},{"line_number":1468,"context_line":"            if future.cancelled():"}],"source_content_type":"text/x-python","patch_set":5,"id":"e41d6193_257b97c6","line":1465,"range":{"start_line":1465,"start_character":27,"end_line":1465,"end_character":34},"updated":"2026-01-27 15:36:51.000000000","message":"nit: poison","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"fa99811e6a10884a7feee14c2f474d126d9143e6","unresolved":false,"context_lines":[{"line_number":1462,"context_line":"            if future is self._poison:"},{"line_number":1463,"context_line":"                # We are asked to terminate so exit the loop."},{"line_number":1464,"context_line":"                self._queue.task_done()"},{"line_number":1465,"context_line":"                print(\"got poision, returning\")"},{"line_number":1466,"context_line":"                return"},{"line_number":1467,"context_line":""},{"line_number":1468,"context_line":"            if future.cancelled():"}],"source_content_type":"text/x-python","patch_set":5,"id":"1c04b3c8_987f787f","line":1465,"range":{"start_line":1465,"start_character":27,"end_line":1465,"end_character":34},"in_reply_to":"e41d6193_257b97c6","updated":"2026-01-29 10:31:27.000000000","message":"Acknowledged","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":false,"context_lines":[{"line_number":1469,"context_line":"                # The task was cancelled while it was in the queue."},{"line_number":1470,"context_line":"                # We don\u0027t need to run it. Just move on to the next task"},{"line_number":1471,"context_line":"                print(\"next future is cancelled while in queue\", fn, future)"},{"line_number":1472,"context_line":"                self._queue.task_done()"},{"line_number":1473,"context_line":"                continue"},{"line_number":1474,"context_line":""},{"line_number":1475,"context_line":"            # The task is still valid, wait for its deadline"}],"source_content_type":"text/x-python","patch_set":5,"id":"9e71d38d_5c15b866","line":1472,"updated":"2026-01-27 15:36:51.000000000","message":"++","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":false,"context_lines":[{"line_number":1475,"context_line":"            # The task is still valid, wait for its deadline"},{"line_number":1476,"context_line":"            wait_remaining \u003d deadline - time.monotonic()"},{"line_number":1477,"context_line":"            if wait_remaining \u003e 0:"},{"line_number":1478,"context_line":"                # Blocking here is fine as we have the assumption that"},{"line_number":1479,"context_line":"                # no new task can arrive that has a deadline that is sooner"},{"line_number":1480,"context_line":"                # than the deadline of the oldest task in the queue due to"},{"line_number":1481,"context_line":"                # our static delay (and we assume that time travel is not"}],"source_content_type":"text/x-python","patch_set":5,"id":"de59be3c_f2fd674c","line":1478,"range":{"start_line":1478,"start_character":18,"end_line":1478,"end_character":39},"updated":"2026-01-27 15:36:51.000000000","message":"agreed on that","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":true,"context_lines":[{"line_number":1481,"context_line":"                # our static delay (and we assume that time travel is not"},{"line_number":1482,"context_line":"                # allowed)."},{"line_number":1483,"context_line":"                print(\"waiting for deadline\", fn, future, wait_remaining)"},{"line_number":1484,"context_line":"                time.sleep(wait_remaining)"},{"line_number":1485,"context_line":""},{"line_number":1486,"context_line":"            # It is time to run the task"},{"line_number":1487,"context_line":"            run_it \u003d future.set_running_or_notify_cancel()"}],"source_content_type":"text/x-python","patch_set":5,"id":"3daf20f1_aedb22ac","line":1484,"updated":"2026-01-27 15:36:51.000000000","message":"an alternative instead of that blocking call would be to push the task back in the queue (at the end) but that would unprioritize the fn call AFAICU.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7b2f84a17ff82c7a99976e1678e2d266f31a02d2","unresolved":false,"context_lines":[{"line_number":1481,"context_line":"                # our static delay (and we assume that time travel is not"},{"line_number":1482,"context_line":"                # allowed)."},{"line_number":1483,"context_line":"                print(\"waiting for deadline\", fn, future, wait_remaining)"},{"line_number":1484,"context_line":"                time.sleep(wait_remaining)"},{"line_number":1485,"context_line":""},{"line_number":1486,"context_line":"            # It is time to run the task"},{"line_number":1487,"context_line":"            run_it \u003d future.set_running_or_notify_cancel()"}],"source_content_type":"text/x-python","patch_set":5,"id":"d912fcfc_3e1f991a","line":1484,"in_reply_to":"3799d246_91a891f6","updated":"2026-02-02 14:05:58.000000000","message":"I improved on this it will not block the shutdown if the tasks are cancelled before the shutdown","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d5e54548cc30af0ba4ea64fbe12e6d13d598341e","unresolved":true,"context_lines":[{"line_number":1481,"context_line":"                # our static delay (and we assume that time travel is not"},{"line_number":1482,"context_line":"                # allowed)."},{"line_number":1483,"context_line":"                print(\"waiting for deadline\", fn, future, wait_remaining)"},{"line_number":1484,"context_line":"                time.sleep(wait_remaining)"},{"line_number":1485,"context_line":""},{"line_number":1486,"context_line":"            # It is time to run the task"},{"line_number":1487,"context_line":"            run_it \u003d future.set_running_or_notify_cancel()"}],"source_content_type":"text/x-python","patch_set":5,"id":"7e1d475d_1a1e9a42","line":1484,"in_reply_to":"3daf20f1_aedb22ac","updated":"2026-01-27 18:47:33.000000000","message":"that would create a busy loop continuously taking the next task out from the queue and pushing it back to the queue.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":true,"context_lines":[{"line_number":1481,"context_line":"                # our static delay (and we assume that time travel is not"},{"line_number":1482,"context_line":"                # allowed)."},{"line_number":1483,"context_line":"                print(\"waiting for deadline\", fn, future, wait_remaining)"},{"line_number":1484,"context_line":"                time.sleep(wait_remaining)"},{"line_number":1485,"context_line":""},{"line_number":1486,"context_line":"            # It is time to run the task"},{"line_number":1487,"context_line":"            run_it \u003d future.set_running_or_notify_cancel()"}],"source_content_type":"text/x-python","patch_set":5,"id":"f307d1f9_e3fa700a","line":1484,"in_reply_to":"7e1d475d_1a1e9a42","updated":"2026-02-01 04:46:27.000000000","message":"one problem with this blocking call is that it will also block the shutdown (graceful shutdown as overall). If shutdown is initiated any time, it should just stop the things right away and only wait for actual in-progress tasks (tasks in progress in actual executor thread).\n\nmaybe we should remove the  time.sleep(wait_remaining) and do sleep for .5 sec and continue thw while loop so that it can check the shutdown and exit on regilar interval.\n            if wait_remaining \u003e 0:\n                # Blocking here is fine as we have the assumption that\n                # no new task can arrive that has a deadline that is sooner\n                # than the deadline of the oldest task in the queue due to\n                # our static delay (and we assume that time travel is not\n                # allowed).\n                print(\"waiting for deadline\", fn, future, wait_remaining)\n                time.sleep(.5)\n                continue","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"bcfb6fc9793b9c840386fcf070f4dabbe6eb6b2e","unresolved":false,"context_lines":[{"line_number":1481,"context_line":"                # our static delay (and we assume that time travel is not"},{"line_number":1482,"context_line":"                # allowed)."},{"line_number":1483,"context_line":"                print(\"waiting for deadline\", fn, future, wait_remaining)"},{"line_number":1484,"context_line":"                time.sleep(wait_remaining)"},{"line_number":1485,"context_line":""},{"line_number":1486,"context_line":"            # It is time to run the task"},{"line_number":1487,"context_line":"            run_it \u003d future.set_running_or_notify_cancel()"}],"source_content_type":"text/x-python","patch_set":5,"id":"fa94860b_bfbf078e","line":1484,"in_reply_to":"d912fcfc_3e1f991a","updated":"2026-02-02 18:51:29.000000000","message":"++, that is even better","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":false,"context_lines":[{"line_number":1481,"context_line":"                # our static delay (and we assume that time travel is not"},{"line_number":1482,"context_line":"                # allowed)."},{"line_number":1483,"context_line":"                print(\"waiting for deadline\", fn, future, wait_remaining)"},{"line_number":1484,"context_line":"                time.sleep(wait_remaining)"},{"line_number":1485,"context_line":""},{"line_number":1486,"context_line":"            # It is time to run the task"},{"line_number":1487,"context_line":"            run_it \u003d future.set_running_or_notify_cancel()"}],"source_content_type":"text/x-python","patch_set":5,"id":"3799d246_91a891f6","line":1484,"in_reply_to":"f307d1f9_e3fa700a","updated":"2026-02-02 01:17:44.000000000","message":"After rethnking on it from graceful shutdown perspective, the proposed way is fine.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":false,"context_lines":[{"line_number":1514,"context_line":"        print(\"task submitted to wrapper\", fn)"},{"line_number":1515,"context_line":"        # We need this wide locking as we don\u0027t want to queue a task behind"},{"line_number":1516,"context_line":"        # the poison as that task will never be processed."},{"line_number":1517,"context_line":"        with self._shutdown_lock:"},{"line_number":1518,"context_line":"            if self._shutdown:"},{"line_number":1519,"context_line":"                raise RuntimeError("},{"line_number":1520,"context_line":"                    \"Cannot schedule new tasks after being shutdown\")"}],"source_content_type":"text/x-python","patch_set":5,"id":"5c2c1a19_3f02fa8d","line":1517,"updated":"2026-01-27 15:36:51.000000000","message":"that\u0027s an instance thread lock, so we\u0027re safe to look at it.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":false,"context_lines":[{"line_number":1542,"context_line":"        # to exit by queuing up a poison task after the shutdown condition"},{"line_number":1543,"context_line":"        # is set. This task won\u0027t be executed."},{"line_number":1544,"context_line":"        self._queue.put("},{"line_number":1545,"context_line":"            (time.monotonic(), lambda: None, [], {}, self._poison))"},{"line_number":1546,"context_line":"        print(\"poison queued\")"},{"line_number":1547,"context_line":"        # If wait is set we need to wait for our poison to be processed and"},{"line_number":1548,"context_line":"        # therefore our thread to exit."}],"source_content_type":"text/x-python","patch_set":5,"id":"de55d48c_207bbe49","line":1545,"updated":"2026-01-27 15:36:51.000000000","message":"yeah, that\u0027s the sentinel that we inject here and what is read line 1462.","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":false,"context_lines":[{"line_number":1413,"context_line":"        return tpool.Proxy(target, autowrap\u003dautowrap)"},{"line_number":1414,"context_line":""},{"line_number":1415,"context_line":""},{"line_number":1416,"context_line":"class StaticallyDelayingCancellableTaskExecutorWrapper:"},{"line_number":1417,"context_line":"    \"\"\"Executor wrapper that submit work to another executor but delays each"},{"line_number":1418,"context_line":"    task\u0027s submission with a statically defined delay and supports cancelling"},{"line_number":1419,"context_line":"    the task during such delay."}],"source_content_type":"text/x-python","patch_set":9,"id":"d043c6bf_77876328","line":1416,"range":{"start_line":1416,"start_character":6,"end_line":1416,"end_character":54},"updated":"2026-02-01 04:46:27.000000000","message":"I do not think anyone need to read the doc string after this name :)","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":true,"context_lines":[{"line_number":1480,"context_line":"            deadline, fn, args, kwargs, future \u003d self._queue.get()"},{"line_number":1481,"context_line":"            print(\"next task\", fn, future)"},{"line_number":1482,"context_line":""},{"line_number":1483,"context_line":"            if future is self._sentinel:"},{"line_number":1484,"context_line":"                # We are asked to terminate so exit the loop."},{"line_number":1485,"context_line":"                self._queue.task_done()"},{"line_number":1486,"context_line":"                print(\"got poision, returning\")"}],"source_content_type":"text/x-python","patch_set":9,"id":"b3780d6d_e0811166","line":1483,"range":{"start_line":1483,"start_character":0,"end_line":1483,"end_character":40},"updated":"2026-02-01 04:46:27.000000000","message":"I think we need to change the logic of shutdown monitoring. self._sentinel way will let shudtown to wait for all the delayed tasks to be submitted. Where, shutdown should only wait for self._thread to finish which will be nothing than to wait when tasks are in-progress of submitting to actual executor (mainly L1525). We just need to make sure shutdown does not interupt the  self._executor.submit( (L1525) part.\n\nwe should check if self._shutdown: so that if shutdown is initiated then we do not just sleep for the deadlines of all submitted tasks instead exit this method and soe does self._thread","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":false,"context_lines":[{"line_number":1480,"context_line":"            deadline, fn, args, kwargs, future \u003d self._queue.get()"},{"line_number":1481,"context_line":"            print(\"next task\", fn, future)"},{"line_number":1482,"context_line":""},{"line_number":1483,"context_line":"            if future is self._sentinel:"},{"line_number":1484,"context_line":"                # We are asked to terminate so exit the loop."},{"line_number":1485,"context_line":"                self._queue.task_done()"},{"line_number":1486,"context_line":"                print(\"got poision, returning\")"}],"source_content_type":"text/x-python","patch_set":9,"id":"6fc5ee0f_72e1ebd4","line":1483,"range":{"start_line":1483,"start_character":0,"end_line":1483,"end_character":40},"in_reply_to":"b3780d6d_e0811166","updated":"2026-02-02 01:17:44.000000000","message":"I gave second thought on it and now I agree that the currect propoased way is correct path.\n\nIf event is submitted by the libvirt then completing that (even its a 15 sec wait in worst case) during shutdown is graceful way. And these 15 sec + task after event is triggered should be covered in parallel to other operation/wait happening during graceful shutdown.","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":false,"context_lines":[{"line_number":1485,"context_line":"                self._queue.task_done()"},{"line_number":1486,"context_line":"                print(\"got poision, returning\")"},{"line_number":1487,"context_line":"                return"},{"line_number":1488,"context_line":""},{"line_number":1489,"context_line":"            if future.cancelled():"},{"line_number":1490,"context_line":"                # The task was cancelled while it was in the queue."},{"line_number":1491,"context_line":"                # We don\u0027t need to run it. Just move on to the next task"},{"line_number":1492,"context_line":"                print(\"next future is cancelled while in queue\", fn, future)"}],"source_content_type":"text/x-python","patch_set":9,"id":"11c180d3_1cb89833","line":1489,"range":{"start_line":1488,"start_character":0,"end_line":1489,"end_character":34},"updated":"2026-02-01 04:46:27.000000000","message":"future synchronize the cancel() and cancelled() using threading.Condition() so we are safe here for parallel check if task is in state of cancelation.","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":false,"context_lines":[{"line_number":1505,"context_line":"                time.sleep(wait_remaining)"},{"line_number":1506,"context_line":""},{"line_number":1507,"context_line":"            # It is time to run the task"},{"line_number":1508,"context_line":"            run_it \u003d future.set_running_or_notify_cancel()"},{"line_number":1509,"context_line":"            if not run_it:"},{"line_number":1510,"context_line":"                # The task was cancelled during the delay period."},{"line_number":1511,"context_line":"                # We don\u0027t need to run it. Just move on to the next task."}],"source_content_type":"text/x-python","patch_set":9,"id":"18c55bbd_6f2e1608","line":1508,"range":{"start_line":1508,"start_character":27,"end_line":1508,"end_character":58},"updated":"2026-02-01 04:46:27.000000000","message":"++, this is another last check for canceled tasks before we actually run.","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":true,"context_lines":[{"line_number":1522,"context_line":"            # thread executing the wrapper. The worker thread sees the variable"},{"line_number":1523,"context_line":"            # binding of fn, future,... changing as this thread takes the next"},{"line_number":1524,"context_line":"            # task from the queue."},{"line_number":1525,"context_line":"            self._executor.submit(self.task_wrapper, fn, args, kwargs, future)"},{"line_number":1526,"context_line":"            # The task is not done from the executor perspective, but it is"},{"line_number":1527,"context_line":"            # done from the _run() logic perspective. Signal it, so shutdown()"},{"line_number":1528,"context_line":"            # can use Queue.join()"}],"source_content_type":"text/x-python","patch_set":9,"id":"194c8878_41587545","line":1525,"range":{"start_line":1525,"start_character":0,"end_line":1525,"end_character":78},"updated":"2026-02-01 04:46:27.000000000","message":"so here we are actually submitting the tasks but shutdown the checked before waiting for delay L1483. If shutdown is initiated during the delay then we should not submit the tasks to real executor and just exit. This will be better from graceful shutdown perspective also to only \"wait for the actual in-progress tasks\" and not to wait for \"the future schedule things (these delayed tasks) to be scheduled and finish\".\n\nIn that case we can check the shutdown again here\n\n            if self._shutdown:\n                return\n            self._executor.submit(self.task_wrapper, fn, args, kwargs, future)","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"89ede8765d13c181f9f8f94c98c91bf561f85290","unresolved":false,"context_lines":[{"line_number":1522,"context_line":"            # thread executing the wrapper. The worker thread sees the variable"},{"line_number":1523,"context_line":"            # binding of fn, future,... changing as this thread takes the next"},{"line_number":1524,"context_line":"            # task from the queue."},{"line_number":1525,"context_line":"            self._executor.submit(self.task_wrapper, fn, args, kwargs, future)"},{"line_number":1526,"context_line":"            # The task is not done from the executor perspective, but it is"},{"line_number":1527,"context_line":"            # done from the _run() logic perspective. Signal it, so shutdown()"},{"line_number":1528,"context_line":"            # can use Queue.join()"}],"source_content_type":"text/x-python","patch_set":9,"id":"e43be1be_aabef309","line":1525,"range":{"start_line":1525,"start_character":0,"end_line":1525,"end_character":78},"in_reply_to":"194c8878_41587545","updated":"2026-02-02 01:17:44.000000000","message":"ignore this comment, I replied on previous comments about shutdown things.","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":true,"context_lines":[{"line_number":1549,"context_line":"            # will be set on this future when available."},{"line_number":1550,"context_line":"            future \u003d futurist.Future()"},{"line_number":1551,"context_line":"            self._queue.put((deadline, fn, args, kwargs, future))"},{"line_number":1552,"context_line":"            print(\"task queued to wrapper\", fn, future)"},{"line_number":1553,"context_line":"            return future"},{"line_number":1554,"context_line":""},{"line_number":1555,"context_line":"    def shutdown(self, wait: bool \u003d True):"}],"source_content_type":"text/x-python","patch_set":9,"id":"f5af3868_9bf16fe7","line":1552,"range":{"start_line":1552,"start_character":12,"end_line":1552,"end_character":55},"updated":"2026-02-01 04:46:27.000000000","message":"if you will convert this to log message, please add \u0027deadline\u0027 also","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7b2f84a17ff82c7a99976e1678e2d266f31a02d2","unresolved":false,"context_lines":[{"line_number":1549,"context_line":"            # will be set on this future when available."},{"line_number":1550,"context_line":"            future \u003d futurist.Future()"},{"line_number":1551,"context_line":"            self._queue.put((deadline, fn, args, kwargs, future))"},{"line_number":1552,"context_line":"            print(\"task queued to wrapper\", fn, future)"},{"line_number":1553,"context_line":"            return future"},{"line_number":1554,"context_line":""},{"line_number":1555,"context_line":"    def shutdown(self, wait: bool \u003d True):"}],"source_content_type":"text/x-python","patch_set":9,"id":"5ac77175_f885905d","line":1552,"range":{"start_line":1552,"start_character":12,"end_line":1552,"end_character":55},"in_reply_to":"f5af3868_9bf16fe7","updated":"2026-02-02 14:05:58.000000000","message":"Done","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":false,"context_lines":[{"line_number":1567,"context_line":""},{"line_number":1568,"context_line":"        # If wait is set we need to wait for our sentinel to be processed and"},{"line_number":1569,"context_line":"        # therefore our thread to exit."},{"line_number":1570,"context_line":"        # NOTE(gibi): We are intentionally not shutting down the real executor"},{"line_number":1571,"context_line":"        # as we are not the one created it or owning it so it might be shared"},{"line_number":1572,"context_line":"        # between different callers."},{"line_number":1573,"context_line":"        if wait:"},{"line_number":1574,"context_line":"            self._queue.join()"},{"line_number":1575,"context_line":"            print(\"queue joined\")"}],"source_content_type":"text/x-python","patch_set":9,"id":"a99b92ed_1ab08c6e","line":1572,"range":{"start_line":1570,"start_character":0,"end_line":1572,"end_character":36},"updated":"2026-02-01 04:46:27.000000000","message":"true, shuting down the resources this wrapper create is a clean way. We may need some generic method in utils to gracefully shutdown all the created executors but that we can do as part of graceful shutdown work.\n\nHere I agree that this wrapper should be responsible for its own termination and exit.","commit_id":"6fb283413049b0808d9c0a3d736bdff426006ddf"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9d9d1e4a0b49c37834b3cdab46d887f90aa6b0be","unresolved":true,"context_lines":[{"line_number":1503,"context_line":"        If True is returned the future in the task is also atomically set to"},{"line_number":1504,"context_line":"        running state and the future cannot be cancelled any more."},{"line_number":1505,"context_line":"        \"\"\""},{"line_number":1506,"context_line":"        if task.remaining_delay \u003c\u003d 0:"},{"line_number":1507,"context_line":"            return task.future.set_running_or_notify_cancel()"},{"line_number":1508,"context_line":""},{"line_number":1509,"context_line":"        self._log(\"Waitig for the deadline of %s\", task)"},{"line_number":1510,"context_line":"        with self._shutdown:"},{"line_number":1511,"context_line":"            shutdown \u003d self._shutdown.wait_for("},{"line_number":1512,"context_line":"                lambda: self._shutdown_requested, task.remaining_delay)"},{"line_number":1513,"context_line":""},{"line_number":1514,"context_line":"        if shutdown:"},{"line_number":1515,"context_line":"            self._log("}],"source_content_type":"text/x-python","patch_set":11,"id":"597be334_afaa6a5f","line":1512,"range":{"start_line":1506,"start_character":0,"end_line":1512,"end_character":71},"updated":"2026-02-02 14:16:17.000000000","message":"Don\u0027t calculate remaing_delay twice that can result in the second calc returning \u003c 0 causing issues.","commit_id":"81c533ad6e7655013bd861554bd25d87df1017f9"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"6768416b6902edacbea4b4bed375eabf1f6d7cf6","unresolved":false,"context_lines":[{"line_number":1503,"context_line":"        If True is returned the future in the task is also atomically set to"},{"line_number":1504,"context_line":"        running state and the future cannot be cancelled any more."},{"line_number":1505,"context_line":"        \"\"\""},{"line_number":1506,"context_line":"        if task.remaining_delay \u003c\u003d 0:"},{"line_number":1507,"context_line":"            return task.future.set_running_or_notify_cancel()"},{"line_number":1508,"context_line":""},{"line_number":1509,"context_line":"        self._log(\"Waitig for the deadline of %s\", task)"},{"line_number":1510,"context_line":"        with self._shutdown:"},{"line_number":1511,"context_line":"            shutdown \u003d self._shutdown.wait_for("},{"line_number":1512,"context_line":"                lambda: self._shutdown_requested, task.remaining_delay)"},{"line_number":1513,"context_line":""},{"line_number":1514,"context_line":"        if shutdown:"},{"line_number":1515,"context_line":"            self._log("}],"source_content_type":"text/x-python","patch_set":11,"id":"cbb6c7f6_881a4b82","line":1512,"range":{"start_line":1506,"start_character":0,"end_line":1512,"end_character":71},"in_reply_to":"597be334_afaa6a5f","updated":"2026-02-02 15:52:18.000000000","message":"Done","commit_id":"81c533ad6e7655013bd861554bd25d87df1017f9"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4d7839822ebd96bb0c7031ba656eb6c0642ebb81","unresolved":true,"context_lines":[{"line_number":1503,"context_line":"        If True is returned the future in the task is also atomically set to"},{"line_number":1504,"context_line":"        running state and the future cannot be cancelled any more."},{"line_number":1505,"context_line":"        \"\"\""},{"line_number":1506,"context_line":"        if task.remaining_delay \u003c\u003d 0:"},{"line_number":1507,"context_line":"            return task.future.set_running_or_notify_cancel()"},{"line_number":1508,"context_line":""},{"line_number":1509,"context_line":"        self._log(\"Waitig for the deadline of %s\", task)"},{"line_number":1510,"context_line":"        with self._shutdown:"},{"line_number":1511,"context_line":"            shutdown \u003d self._shutdown.wait_for("},{"line_number":1512,"context_line":"                lambda: self._shutdown_requested, task.remaining_delay)"},{"line_number":1513,"context_line":""},{"line_number":1514,"context_line":"        if shutdown:"},{"line_number":1515,"context_line":"            self._log("}],"source_content_type":"text/x-python","patch_set":11,"id":"c5a5982a_7ae9be28","line":1512,"range":{"start_line":1506,"start_character":0,"end_line":1512,"end_character":71},"in_reply_to":"aa3b03d2_dbd383fb","updated":"2026-02-02 19:24:51.000000000","message":"\u003e that would not be an issue as 0 or negative value in timeout will still canculate the condition once and return the results immidaitly\n\nAhh OK. I probably remembered from Lock that wait can only be positive. But condition has no such limitation.\n\n\u003e If we consider the multiple thread case, not calcualting remaing_delay again can be problem when 1st thread enter and 2nd thread is waiting for self._shutdown (at L1512). In that case, remaining_delay for 2nd thread will be stale.\n\nGood point. The remaining_delay should have been recalculated once we are within the lock. But it is a moot point now as you correctly identified that a negative wait also works for Condition.\n\n\u003d\u003e I will drop the pre-calculation.","commit_id":"81c533ad6e7655013bd861554bd25d87df1017f9"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"ea03bd1ad4a3f9955c5211d174daf28c5bda4296","unresolved":false,"context_lines":[{"line_number":1503,"context_line":"        If True is returned the future in the task is also atomically set to"},{"line_number":1504,"context_line":"        running state and the future cannot be cancelled any more."},{"line_number":1505,"context_line":"        \"\"\""},{"line_number":1506,"context_line":"        if task.remaining_delay \u003c\u003d 0:"},{"line_number":1507,"context_line":"            return task.future.set_running_or_notify_cancel()"},{"line_number":1508,"context_line":""},{"line_number":1509,"context_line":"        self._log(\"Waitig for the deadline of %s\", task)"},{"line_number":1510,"context_line":"        with self._shutdown:"},{"line_number":1511,"context_line":"            shutdown \u003d self._shutdown.wait_for("},{"line_number":1512,"context_line":"                lambda: self._shutdown_requested, task.remaining_delay)"},{"line_number":1513,"context_line":""},{"line_number":1514,"context_line":"        if shutdown:"},{"line_number":1515,"context_line":"            self._log("}],"source_content_type":"text/x-python","patch_set":11,"id":"89970a79_ce13877f","line":1512,"range":{"start_line":1506,"start_character":0,"end_line":1512,"end_character":71},"in_reply_to":"c5a5982a_7ae9be28","updated":"2026-02-03 10:56:30.000000000","message":"Done","commit_id":"81c533ad6e7655013bd861554bd25d87df1017f9"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"bcfb6fc9793b9c840386fcf070f4dabbe6eb6b2e","unresolved":true,"context_lines":[{"line_number":1503,"context_line":"        If True is returned the future in the task is also atomically set to"},{"line_number":1504,"context_line":"        running state and the future cannot be cancelled any more."},{"line_number":1505,"context_line":"        \"\"\""},{"line_number":1506,"context_line":"        if task.remaining_delay \u003c\u003d 0:"},{"line_number":1507,"context_line":"            return task.future.set_running_or_notify_cancel()"},{"line_number":1508,"context_line":""},{"line_number":1509,"context_line":"        self._log(\"Waitig for the deadline of %s\", task)"},{"line_number":1510,"context_line":"        with self._shutdown:"},{"line_number":1511,"context_line":"            shutdown \u003d self._shutdown.wait_for("},{"line_number":1512,"context_line":"                lambda: self._shutdown_requested, task.remaining_delay)"},{"line_number":1513,"context_line":""},{"line_number":1514,"context_line":"        if shutdown:"},{"line_number":1515,"context_line":"            self._log("}],"source_content_type":"text/x-python","patch_set":11,"id":"aa3b03d2_dbd383fb","line":1512,"range":{"start_line":1506,"start_character":0,"end_line":1512,"end_character":71},"in_reply_to":"cbb6c7f6_881a4b82","updated":"2026-02-02 18:51:29.000000000","message":"that would not be an issue as 0 or negative value in timeout will still canculate the condition once and return the results immidaitly. If we consider the multiple thread case, not calcualting remaing_delay again can be problem when 1st thread enter and 2nd thread is waiting for self._shutdown (at L1512). In that case, remaining_delay for 2nd thread will be stale.","commit_id":"81c533ad6e7655013bd861554bd25d87df1017f9"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9d9d1e4a0b49c37834b3cdab46d887f90aa6b0be","unresolved":true,"context_lines":[{"line_number":1522,"context_line":"            self._log("},{"line_number":1523,"context_line":"                \"%s is not cancelled so still waiting for its \""},{"line_number":1524,"context_line":"                \"deadline\", task)"},{"line_number":1525,"context_line":"            if task.remaining_delay \u003e 0:"},{"line_number":1526,"context_line":"                # Blocking here is fine as we have the assumption that"},{"line_number":1527,"context_line":"                # no new task can arrive that has a deadline that is sooner"},{"line_number":1528,"context_line":"                # than the deadline of the oldest task in the queue due to"},{"line_number":1529,"context_line":"                # our static delay (and we assume that time travel is not"},{"line_number":1530,"context_line":"                # allowed)."},{"line_number":1531,"context_line":"                time.sleep(task.remaining_delay)"},{"line_number":1532,"context_line":""},{"line_number":1533,"context_line":"        return task.future.set_running_or_notify_cancel()"},{"line_number":1534,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"a81af008_16c68758","line":1531,"range":{"start_line":1525,"start_character":0,"end_line":1531,"end_character":48},"updated":"2026-02-02 14:16:17.000000000","message":"ditto","commit_id":"81c533ad6e7655013bd861554bd25d87df1017f9"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"6768416b6902edacbea4b4bed375eabf1f6d7cf6","unresolved":false,"context_lines":[{"line_number":1522,"context_line":"            self._log("},{"line_number":1523,"context_line":"                \"%s is not cancelled so still waiting for its \""},{"line_number":1524,"context_line":"                \"deadline\", task)"},{"line_number":1525,"context_line":"            if task.remaining_delay \u003e 0:"},{"line_number":1526,"context_line":"                # Blocking here is fine as we have the assumption that"},{"line_number":1527,"context_line":"                # no new task can arrive that has a deadline that is sooner"},{"line_number":1528,"context_line":"                # than the deadline of the oldest task in the queue due to"},{"line_number":1529,"context_line":"                # our static delay (and we assume that time travel is not"},{"line_number":1530,"context_line":"                # allowed)."},{"line_number":1531,"context_line":"                time.sleep(task.remaining_delay)"},{"line_number":1532,"context_line":""},{"line_number":1533,"context_line":"        return task.future.set_running_or_notify_cancel()"},{"line_number":1534,"context_line":""}],"source_content_type":"text/x-python","patch_set":11,"id":"9585fbf0_b6b0e87c","line":1531,"range":{"start_line":1525,"start_character":0,"end_line":1531,"end_character":48},"in_reply_to":"a81af008_16c68758","updated":"2026-02-02 15:52:18.000000000","message":"Done","commit_id":"81c533ad6e7655013bd861554bd25d87df1017f9"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9623bd21d2a5d086f801387db24fb8bba0b07bbd","unresolved":true,"context_lines":[{"line_number":1565,"context_line":"            # Push the task to the real executor. We don\u0027t need to wait"},{"line_number":1566,"context_line":"            # for the result here as the client can do that"},{"line_number":1567,"context_line":"            # via the task.future we already returned from submit_with_delay()"},{"line_number":1568,"context_line":"            self._executor.submit(self._task_wrapper, task)"},{"line_number":1569,"context_line":"            self._log(\"%s submitted to %s\", task, self._executor)"},{"line_number":1570,"context_line":"            # The task is not done from the executor perspective, but it is"},{"line_number":1571,"context_line":"            # done from the _run() logic perspective. Signal it, so shutdown()"}],"source_content_type":"text/x-python","patch_set":11,"id":"5ab7cff6_05ce352b","line":1568,"updated":"2026-02-02 15:43:11.000000000","message":"This can raise and that breaks our thread. Need to catch, and propagate","commit_id":"81c533ad6e7655013bd861554bd25d87df1017f9"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"6768416b6902edacbea4b4bed375eabf1f6d7cf6","unresolved":false,"context_lines":[{"line_number":1565,"context_line":"            # Push the task to the real executor. We don\u0027t need to wait"},{"line_number":1566,"context_line":"            # for the result here as the client can do that"},{"line_number":1567,"context_line":"            # via the task.future we already returned from submit_with_delay()"},{"line_number":1568,"context_line":"            self._executor.submit(self._task_wrapper, task)"},{"line_number":1569,"context_line":"            self._log(\"%s submitted to %s\", task, self._executor)"},{"line_number":1570,"context_line":"            # The task is not done from the executor perspective, but it is"},{"line_number":1571,"context_line":"            # done from the _run() logic perspective. Signal it, so shutdown()"}],"source_content_type":"text/x-python","patch_set":11,"id":"12818623_31696c1d","line":1568,"in_reply_to":"5ab7cff6_05ce352b","updated":"2026-02-02 15:52:18.000000000","message":"Done","commit_id":"81c533ad6e7655013bd861554bd25d87df1017f9"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"bcfb6fc9793b9c840386fcf070f4dabbe6eb6b2e","unresolved":true,"context_lines":[{"line_number":1574,"context_line":"                # If for any reason we cannot submit a task then we should not"},{"line_number":1575,"context_line":"                # let the exception escape as that will prevent our thread"},{"line_number":1576,"context_line":"                # to terminate cleanly. Instead we log and propagate back."},{"line_number":1577,"context_line":"                LOG.exception(\"Failed to submit task to executor\")"},{"line_number":1578,"context_line":"                task.future.set_exception(e)"},{"line_number":1579,"context_line":"                self._queue.task_done()"},{"line_number":1580,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":12,"id":"34c669e2_40614669","line":1577,"range":{"start_line":1577,"start_character":48,"end_line":1577,"end_character":64},"updated":"2026-02-02 18:51:29.000000000","message":"let\u0027s log exception, task, and self._executor to know which one is failed and why","commit_id":"33752ae1934f8a9f8cda9d7d6ed00a04d7625816"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"4d7839822ebd96bb0c7031ba656eb6c0642ebb81","unresolved":true,"context_lines":[{"line_number":1574,"context_line":"                # If for any reason we cannot submit a task then we should not"},{"line_number":1575,"context_line":"                # let the exception escape as that will prevent our thread"},{"line_number":1576,"context_line":"                # to terminate cleanly. Instead we log and propagate back."},{"line_number":1577,"context_line":"                LOG.exception(\"Failed to submit task to executor\")"},{"line_number":1578,"context_line":"                task.future.set_exception(e)"},{"line_number":1579,"context_line":"                self._queue.task_done()"},{"line_number":1580,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":12,"id":"5c40c5ee_cb487820","line":1577,"range":{"start_line":1577,"start_character":48,"end_line":1577,"end_character":64},"in_reply_to":"34c669e2_40614669","updated":"2026-02-02 19:24:51.000000000","message":"I think LOG.exception logs the exception in scope. I can add the rest.","commit_id":"33752ae1934f8a9f8cda9d7d6ed00a04d7625816"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"ea03bd1ad4a3f9955c5211d174daf28c5bda4296","unresolved":false,"context_lines":[{"line_number":1574,"context_line":"                # If for any reason we cannot submit a task then we should not"},{"line_number":1575,"context_line":"                # let the exception escape as that will prevent our thread"},{"line_number":1576,"context_line":"                # to terminate cleanly. Instead we log and propagate back."},{"line_number":1577,"context_line":"                LOG.exception(\"Failed to submit task to executor\")"},{"line_number":1578,"context_line":"                task.future.set_exception(e)"},{"line_number":1579,"context_line":"                self._queue.task_done()"},{"line_number":1580,"context_line":"                continue"}],"source_content_type":"text/x-python","patch_set":12,"id":"140c5462_bd7ff12c","line":1577,"range":{"start_line":1577,"start_character":48,"end_line":1577,"end_character":64},"in_reply_to":"5c40c5ee_cb487820","updated":"2026-02-03 10:56:30.000000000","message":"Done","commit_id":"33752ae1934f8a9f8cda9d7d6ed00a04d7625816"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"fc71ef875013fed4f49028f77f65d8fbd1639438","unresolved":false,"context_lines":[{"line_number":1465,"context_line":"        self._queue: queue.Queue \u003d queue.Queue()"},{"line_number":1466,"context_line":"        self._executor \u003d executor"},{"line_number":1467,"context_line":"        self._delay \u003d delay"},{"line_number":1468,"context_line":"        self._shutdown \u003d threading.Condition()"},{"line_number":1469,"context_line":"        self._shutdown_requested \u003d False"},{"line_number":1470,"context_line":"        self._sentinel \u003d self.Task(0, lambda: None, (), {})"},{"line_number":1471,"context_line":"        # We are intentionally not running our _run() in the executor"}],"source_content_type":"text/x-python","patch_set":13,"id":"628252ad_3c9c8898","line":1468,"range":{"start_line":1468,"start_character":35,"end_line":1468,"end_character":44},"updated":"2026-02-03 14:26:49.000000000","message":"nice change","commit_id":"3fe3b3775a28cd596d2afa9c41751a68b8d945c8"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"fc71ef875013fed4f49028f77f65d8fbd1639438","unresolved":false,"context_lines":[{"line_number":1473,"context_line":"        # and our logic never finishes so it would consume one worker"},{"line_number":1474,"context_line":"        # constantly."},{"line_number":1475,"context_line":"        self._thread \u003d threading.Thread(target\u003dself._run)"},{"line_number":1476,"context_line":"        self._thread.daemon \u003d True"},{"line_number":1477,"context_line":"        self._thread.start()"},{"line_number":1478,"context_line":""},{"line_number":1479,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":13,"id":"0916372b_f9e58641","line":1476,"updated":"2026-02-03 14:26:49.000000000","message":"as said in comments on PS5, graceful shutdown is now handled in https://review.opendev.org/c/openstack/nova/+/975128","commit_id":"3fe3b3775a28cd596d2afa9c41751a68b8d945c8"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"fc71ef875013fed4f49028f77f65d8fbd1639438","unresolved":false,"context_lines":[{"line_number":1523,"context_line":"            self._log("},{"line_number":1524,"context_line":"                \"%s is not cancelled so still waiting for its \""},{"line_number":1525,"context_line":"                \"deadline\", task)"},{"line_number":1526,"context_line":"            if task.remaining_delay \u003e 0:"},{"line_number":1527,"context_line":"                # Blocking here is fine as we have the assumption that"},{"line_number":1528,"context_line":"                # no new task can arrive that has a deadline that is sooner"},{"line_number":1529,"context_line":"                # than the deadline of the oldest task in the queue due to"}],"source_content_type":"text/x-python","patch_set":13,"id":"7726ded2_fdc032f7","line":1526,"range":{"start_line":1526,"start_character":15,"end_line":1526,"end_character":35},"updated":"2026-02-03 14:26:49.000000000","message":"excellent idea, instead of counting the remainder.","commit_id":"3fe3b3775a28cd596d2afa9c41751a68b8d945c8"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"1279a8c59585859b7bd71a9c00080a37c2c35d84","unresolved":false,"context_lines":[{"line_number":1430,"context_line":"    different tasks."},{"line_number":1431,"context_line":"    \"\"\""},{"line_number":1432,"context_line":""},{"line_number":1433,"context_line":"    class Task:"},{"line_number":1434,"context_line":"        def __init__("},{"line_number":1435,"context_line":"            self,"},{"line_number":1436,"context_line":"            delay: float,"}],"source_content_type":"text/x-python","patch_set":14,"id":"ff8ffa56_dd6bb621","line":1433,"updated":"2026-02-04 20:54:20.000000000","message":"nit: this proably didn need to be an inline class def but it will work.","commit_id":"f16170695ccd0097cda47dd87e9c89bc8690122e"}],"nova/virt/libvirt/host.py":[{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ed196653d5037914a08a021076acdaa46f3eb598","unresolved":true,"context_lines":[{"line_number":347,"context_line":"        #                down the domain during a reboot, delay the"},{"line_number":348,"context_line":"        #                STOPPED lifecycle event some seconds."},{"line_number":349,"context_line":"        self._delayed_executor \u003d ("},{"line_number":350,"context_line":"            utils.StaticallyDelayingCancellableTaskExecutorWrapper("},{"line_number":351,"context_line":"                delay\u003d15, executor\u003dutils._get_default_executor()))"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"        self._initialized \u003d False"}],"source_content_type":"text/x-python","patch_set":5,"id":"75f65254_908046ad","line":350,"updated":"2026-01-27 15:36:51.000000000","message":"I love that name 😄","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"d5e54548cc30af0ba4ea64fbe12e6d13d598341e","unresolved":true,"context_lines":[{"line_number":347,"context_line":"        #                down the domain during a reboot, delay the"},{"line_number":348,"context_line":"        #                STOPPED lifecycle event some seconds."},{"line_number":349,"context_line":"        self._delayed_executor \u003d ("},{"line_number":350,"context_line":"            utils.StaticallyDelayingCancellableTaskExecutorWrapper("},{"line_number":351,"context_line":"                delay\u003d15, executor\u003dutils._get_default_executor()))"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"        self._initialized \u003d False"}],"source_content_type":"text/x-python","patch_set":5,"id":"e766696f_a8065358","line":350,"in_reply_to":"75f65254_908046ad","updated":"2026-01-27 18:47:33.000000000","message":"very enterprisey. I should put somewhere a factory for it with an interface maybe or a facade. :)","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"},{"author":{"_account_id":8556,"name":"Ghanshyam Maan","display_name":"Ghanshyam Maan","email":"gmaan.os14@gmail.com","username":"ghanshyam"},"change_message_id":"e5dd7ae5546349c559fbcdf34851d48c682bc209","unresolved":false,"context_lines":[{"line_number":347,"context_line":"        #                down the domain during a reboot, delay the"},{"line_number":348,"context_line":"        #                STOPPED lifecycle event some seconds."},{"line_number":349,"context_line":"        self._delayed_executor \u003d ("},{"line_number":350,"context_line":"            utils.StaticallyDelayingCancellableTaskExecutorWrapper("},{"line_number":351,"context_line":"                delay\u003d15, executor\u003dutils._get_default_executor()))"},{"line_number":352,"context_line":""},{"line_number":353,"context_line":"        self._initialized \u003d False"}],"source_content_type":"text/x-python","patch_set":5,"id":"91560689_54629711","line":350,"in_reply_to":"e766696f_a8065358","updated":"2026-02-01 04:46:27.000000000","message":"indeed :)","commit_id":"f8acc4261b93d3950b674498f21fe3d022a5473e"}]}
