)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":35153,"name":"Ashish Gupta","email":"ashigupt@redhat.com","username":"ashigupt","status":"Redhat"},"change_message_id":"d417482074340de587f83f94c8ebfecb4cddc725","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"31673865_e02e1b40","updated":"2026-06-11 08:46:38.000000000","message":"recheck, functional threading job consistency check","commit_id":"3f20e6e5f182d63d0179bf07a102cc786e2c35b3"},{"author":{"_account_id":35153,"name":"Ashish Gupta","email":"ashigupt@redhat.com","username":"ashigupt","status":"Redhat"},"change_message_id":"aa6e0cb67873dd95d9a66d266c9b32d9bc236f16","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"3ef7ce59_07050e46","updated":"2026-06-11 06:28:06.000000000","message":"recheck, functional threading job consistency check","commit_id":"3f20e6e5f182d63d0179bf07a102cc786e2c35b3"},{"author":{"_account_id":35153,"name":"Ashish Gupta","email":"ashigupt@redhat.com","username":"ashigupt","status":"Redhat"},"change_message_id":"178e9844c1cc97c16b64a394f5618189411e11ad","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"7cc640a2_79639b78","updated":"2026-06-11 10:13:17.000000000","message":"recheck, functional threading job consistency check","commit_id":"3f20e6e5f182d63d0179bf07a102cc786e2c35b3"},{"author":{"_account_id":35153,"name":"Ashish Gupta","email":"ashigupt@redhat.com","username":"ashigupt","status":"Redhat"},"change_message_id":"5b6ecb589c0683bc2ea9f2822f5c0cec75f973ab","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"9146f4f6_524638d0","updated":"2026-06-10 20:49:29.000000000","message":"recheck, functional threading job consistency check","commit_id":"3f20e6e5f182d63d0179bf07a102cc786e2c35b3"}],"nova/tests/functional/fixtures.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"941a44c4ce0c542c562d137a398ec7fdc6c486c5","unresolved":true,"context_lines":[{"line_number":39,"context_line":"_SHARED_PLACEMENT_DB_PATH \u003d None"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"class PlacementDatabaseLock(fixtures.Fixture):"},{"line_number":43,"context_line":"    \"\"\"Serialize Placement database transactions across threads in tests."},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    Patches _TransactionContextManager._transaction_scope for the duration of"}],"source_content_type":"text/x-python","patch_set":7,"id":"4fd81332_332a8007","line":42,"updated":"2026-06-11 12:59:01.000000000","message":"I think the write locking should be enough and no read locking should be needed. The fact that this only works with read locking suggests me that we are missing something. \n\nI will take a look in some local runs to see what could be the problem...\n\n---\n\nWhen we make it work with the write locking only then I suggest to have a single DatabaseLock fixture class that takes a separate lock for each database we manage instead of duplicating this code.\n\nE.g. something like\n```\n    def __init__(self):\n        # to protect the _locks dict\n        self._lock \u003d threading.Lock()\n        # dict of DB URL string to write lock for that DB\n        self._locks \u003d collections.defaultdict(threading.RLock)\n\n    def _get_lock(self, tcm):\n        with self._lock:\n            db_url \u003d tcm.reader.get_engine().url\n            return self._locks[db_url]\n```\n\nI used the DB url as the unique key for this example but maybe tcm_self._root works as well.\n\n---\n\nAlso we can try to avoid the extra lock lookup at each transaction if we inject the lock into the TransactionContextManager itself at first. But we can ignore this optimization for now.","commit_id":"3f20e6e5f182d63d0179bf07a102cc786e2c35b3"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"a1fa40cd596583c9d9df9078632852b5ec8a8699","unresolved":true,"context_lines":[{"line_number":39,"context_line":"_SHARED_PLACEMENT_DB_PATH \u003d None"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"class PlacementDatabaseLock(fixtures.Fixture):"},{"line_number":43,"context_line":"    \"\"\"Serialize Placement database transactions across threads in tests."},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"    Patches _TransactionContextManager._transaction_scope for the duration of"}],"source_content_type":"text/x-python","patch_set":7,"id":"e81ddedb_dd2072a8","line":42,"in_reply_to":"4fd81332_332a8007","updated":"2026-06-11 13:01:36.000000000","message":"\u003e When we make it work with the write locking only then I suggest to have a single DatabaseLock fixture class that takes a separate lock for each database we manage instead of duplicating this code.\n\u003e \n\u003e E.g. something like\n\u003e ```\n\u003e     def __init__(self):\n\u003e         # to protect the _locks dict\n\u003e         self._lock \u003d threading.Lock()\n\u003e         # dict of DB URL string to write lock for that DB\n\u003e         self._locks \u003d collections.defaultdict(threading.RLock)\n\u003e \n\u003e     def _get_lock(self, tcm):\n\u003e         with self._lock:\n\u003e             db_url \u003d tcm.reader.get_engine().url\n\u003e             return self._locks[db_url]\n\u003e ```\n\u003e \n\u003e I used the DB url as the unique key for this example but maybe tcm_self._root works as well.\n\u003e \n\nI see you did something similar in the next patch https://review.opendev.org/c/openstack/nova/+/992862/1 I will comment further there","commit_id":"3f20e6e5f182d63d0179bf07a102cc786e2c35b3"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"941a44c4ce0c542c562d137a398ec7fdc6c486c5","unresolved":true,"context_lines":[{"line_number":147,"context_line":"                _ORIGINAL_DATABASE_SETUP(db_fixture_self)"},{"line_number":148,"context_line":""},{"line_number":149,"context_line":"            # Temporarily replace Database.setUp"},{"line_number":150,"context_line":"            placement_db_fixtures.Database.setUp \u003d patched_database_setup"},{"line_number":151,"context_line":""},{"line_number":152,"context_line":"        super(PlacementFixture, self).setUp()"},{"line_number":153,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"4709d822_f249b5a1","line":150,"updated":"2026-06-11 12:59:01.000000000","message":"Please modify this code in the placement repo directly as needed instead of dynamically patching it at runtime.","commit_id":"3f20e6e5f182d63d0179bf07a102cc786e2c35b3"}]}
