)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":31291,"name":"Eduardo Olivares","email":"eolivare@redhat.com","username":"eolivare"},"change_message_id":"3c4f29c350fd7a9a2803842aa489b2ae3d93817e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"e5add5d6_de2bc93c","updated":"2026-05-12 15:19:54.000000000","message":"recheck neutron-ovn-bgp-tempest-multinode","commit_id":"40b0d1349fb5288771546a839f6d2a9ae8c54838"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"ca991e54b4bbb97943eb26def098157b9686c41e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"4cdff7ab_20c34b2c","updated":"2026-05-14 08:42:14.000000000","message":"BTW, I see errors in the periodic workers process: https://72d8b9e31cc42ce28c21-5ee64c90e88fa7c06fc3e7f7cd052613.ssl.cf2.rackcdn.com/openstack/b803d1fc34954f3fb9b694f03e43090f/controller/logs/screen-neutron-periodic-workers.txt","commit_id":"a2d5b52cdffb0e3c555c234a6480aeed8a0291c2"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"40e633f8a71fed6211f55914754b61ae5edb3692","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"c5a5effe_504ae8cb","updated":"2026-05-14 15:34:35.000000000","message":"Thanks!","commit_id":"491a7723f24312368dfe6c60f809f5d130b42715"},{"author":{"_account_id":31291,"name":"Eduardo Olivares","email":"eolivare@redhat.com","username":"eolivare"},"change_message_id":"31d275905e64e9fd2b1d64ce39ddcbecb9a77e3d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"b4cc4375_500e775a","updated":"2026-05-18 07:33:46.000000000","message":"recheck neutron-ovn-bgp-tempest-multinode (timeout, no test failures)","commit_id":"491a7723f24312368dfe6c60f809f5d130b42715"}],"neutron/services/bgp/reconciler.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"1f01ae869006409c999bdeca10026d2cd93930fd","unresolved":true,"context_lines":[{"line_number":46,"context_line":"                    self.delete_chassis,"},{"line_number":47,"context_line":"            },"},{"line_number":48,"context_line":"        }"},{"line_number":49,"context_line":"        self.nb_api \u003d None"},{"line_number":50,"context_line":"        self.sb_api \u003d None"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    def start(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"a02e5676_3f917ebd","line":49,"updated":"2026-05-14 08:41:40.000000000","message":"I\u0027m executing this patch locally and I\u0027m having the following errors:\n```\nTraceback (most recent call last):\n  File \"/opt/stack/oslo.service/oslo_service/backend/_threading/service.py\", line 130, in run\n    self.service_instance.wait()\n  File \"/opt/stack/neutron/neutron/services/bgp/worker.py\", line 30, in wait\n    self._reconciler.full_sync()\n  File \"/opt/stack/neutron/neutron/services/bgp/reconciler.py\", line 82, in full_sync\n    if not self.nb_api.ovsdb_connection.idl.is_lock_contended:\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nAttributeError: \u0027NoneType\u0027 object has no attribute \u0027ovsdb_connection\u0027\nTraceback (most recent call last):\n  File \"/opt/stack/oslo.service/oslo_service/backend/_threading/service.py\", line 130, in run\n    self.service_instance.wait()\n  File \"/opt/stack/neutron/neutron/services/bgp/worker.py\", line 30, in wait\n    self._reconciler.full_sync()\n  File \"/opt/stack/neutron/neutron/services/bgp/reconciler.py\", line 82, in full_sync\n    if not self.nb_api.ovsdb_connection.idl.is_lock_contended:\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nAttributeError: \u0027NoneType\u0027 object has no attribute \u0027ovsdb_connection\u0027\nTraceback (most recent call last):\n  File \"/opt/stack/oslo.service/oslo_service/backend/_threading/service.py\", line 130, in run\n    self.service_instance.wait()\n  File \"/opt/stack/neutron/neutron/services/bgp/worker.py\", line 30, in wait\n    self._reconciler.full_sync()\n  File \"/opt/stack/neutron/neutron/services/bgp/reconciler.py\", line 82, in full_sync\n    if not self.nb_api.ovsdb_connection.idl.is_lock_contended:\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^\nAttributeError: \u0027NoneType\u0027 object has no attribute \u0027ovsdb_connection\u0027\n```\n\nThe `BGPWorker.wait` method is called before the IDLs are created.","commit_id":"a2d5b52cdffb0e3c555c234a6480aeed8a0291c2"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"3ff19c1026969d5c061531c312f262881cfe2d17","unresolved":false,"context_lines":[{"line_number":46,"context_line":"                    self.delete_chassis,"},{"line_number":47,"context_line":"            },"},{"line_number":48,"context_line":"        }"},{"line_number":49,"context_line":"        self.nb_api \u003d None"},{"line_number":50,"context_line":"        self.sb_api \u003d None"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    def start(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"2b26be30_7a5b76a6","line":49,"in_reply_to":"73d00b81_4afec7e6","updated":"2026-05-14 15:33:31.000000000","message":"Done","commit_id":"a2d5b52cdffb0e3c555c234a6480aeed8a0291c2"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"a6669e2def61a83d62737ad8adf2382033e99546","unresolved":true,"context_lines":[{"line_number":46,"context_line":"                    self.delete_chassis,"},{"line_number":47,"context_line":"            },"},{"line_number":48,"context_line":"        }"},{"line_number":49,"context_line":"        self.nb_api \u003d None"},{"line_number":50,"context_line":"        self.sb_api \u003d None"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    def start(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"73d00b81_4afec7e6","line":49,"in_reply_to":"a02e5676_3f917ebd","updated":"2026-05-14 08:48:05.000000000","message":"It is weird: if I apply the next patch (worker_process_count\u003d1), this error doesn\u0027t appear. As commented in Slack, you should push the patches in reversed order","commit_id":"a2d5b52cdffb0e3c555c234a6480aeed8a0291c2"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"146ff4018588ade3a7bfc2b182f3b49a69a9cd36","unresolved":true,"context_lines":[{"line_number":81,"context_line":"        ]"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    def full_sync(self):"},{"line_number":84,"context_line":"        if not self.nb_api.ovsdb_connection.idl.is_lock_contended:"},{"line_number":85,"context_line":"            LOG.info(\"Full BGP topology synchronization started\")"},{"line_number":86,"context_line":"            # First make sure all chassis are indexed"},{"line_number":87,"context_line":"            commands.FullSyncBGPTopologyCommand("}],"source_content_type":"text/x-python","patch_set":5,"id":"44270ba4_6ed54f27","line":84,"updated":"2026-05-14 12:07:04.000000000","message":"we need to guard here too with a wait event, that\u0027s actually what Rodolfo has seen above.\n\nAlternatively, we can implement a wait method (which makes a little sense for a reconciler) and call it before the full sync.","commit_id":"47c6ecb9ff3459cdcf0d2738fab28a6cb993a55d"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"d246013abed4a6eaf945ba9d5e13ad2594848ebe","unresolved":true,"context_lines":[{"line_number":81,"context_line":"        ]"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    def full_sync(self):"},{"line_number":84,"context_line":"        if not self.nb_api.ovsdb_connection.idl.is_lock_contended:"},{"line_number":85,"context_line":"            LOG.info(\"Full BGP topology synchronization started\")"},{"line_number":86,"context_line":"            # First make sure all chassis are indexed"},{"line_number":87,"context_line":"            commands.FullSyncBGPTopologyCommand("}],"source_content_type":"text/x-python","patch_set":5,"id":"efe40514_af6adb35","line":84,"in_reply_to":"44270ba4_6ed54f27","updated":"2026-05-14 15:29:33.000000000","message":"Shall we also log after we\u0027re done waiting?","commit_id":"47c6ecb9ff3459cdcf0d2738fab28a6cb993a55d"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"3ff19c1026969d5c061531c312f262881cfe2d17","unresolved":false,"context_lines":[{"line_number":81,"context_line":"        ]"},{"line_number":82,"context_line":""},{"line_number":83,"context_line":"    def full_sync(self):"},{"line_number":84,"context_line":"        if not self.nb_api.ovsdb_connection.idl.is_lock_contended:"},{"line_number":85,"context_line":"            LOG.info(\"Full BGP topology synchronization started\")"},{"line_number":86,"context_line":"            # First make sure all chassis are indexed"},{"line_number":87,"context_line":"            commands.FullSyncBGPTopologyCommand("}],"source_content_type":"text/x-python","patch_set":5,"id":"3865231c_af96f6b9","line":84,"in_reply_to":"efe40514_af6adb35","updated":"2026-05-14 15:33:31.000000000","message":"Done","commit_id":"47c6ecb9ff3459cdcf0d2738fab28a6cb993a55d"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"628ab8c7df2c6318c7659f59532539d0c76daf48","unresolved":true,"context_lines":[{"line_number":64,"context_line":"        self._started.set()"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def stop(self):"},{"line_number":67,"context_line":"        if self.nb_api is not None:"},{"line_number":68,"context_line":"            self.nb_api.stop()"},{"line_number":69,"context_line":"        if self.sb_api is not None:"},{"line_number":70,"context_line":"            self.sb_api.stop()"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    @property"},{"line_number":73,"context_line":"    def nb_events(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"c04cf6b4_b924a0d3","line":70,"range":{"start_line":67,"start_character":0,"end_line":70,"end_character":30},"updated":"2026-05-14 12:43:15.000000000","message":"we can reuse the event here since it\u0027s set only if both apis were created\n```\n    if self._started.is_set():\n        self.nb_api.stop()\n        self.sb_api.stop()      \n```","commit_id":"8d55721e5a672dd47fb395d53a89d5f11c4ae52d"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"3ff19c1026969d5c061531c312f262881cfe2d17","unresolved":false,"context_lines":[{"line_number":64,"context_line":"        self._started.set()"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def stop(self):"},{"line_number":67,"context_line":"        if self.nb_api is not None:"},{"line_number":68,"context_line":"            self.nb_api.stop()"},{"line_number":69,"context_line":"        if self.sb_api is not None:"},{"line_number":70,"context_line":"            self.sb_api.stop()"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    @property"},{"line_number":73,"context_line":"    def nb_events(self):"}],"source_content_type":"text/x-python","patch_set":6,"id":"8b4cb185_4fd919c3","line":70,"range":{"start_line":67,"start_character":0,"end_line":70,"end_character":30},"in_reply_to":"c04cf6b4_b924a0d3","updated":"2026-05-14 15:33:31.000000000","message":"Done","commit_id":"8d55721e5a672dd47fb395d53a89d5f11c4ae52d"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"47501d34e8ee0d60e114f67ccc4149759a8c3634","unresolved":true,"context_lines":[{"line_number":61,"context_line":"            ovn_conf.get_ovn_sb_connection(),"},{"line_number":62,"context_line":"            self.sb_events).start("},{"line_number":63,"context_line":"                timeout\u003dovn_conf.get_ovn_ovsdb_timeout())"},{"line_number":64,"context_line":"        self._started.set()"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def stop(self):"},{"line_number":67,"context_line":"        if self._started.is_set():"}],"source_content_type":"text/x-python","patch_set":7,"id":"e4ee7055_86d3e021","line":64,"updated":"2026-05-14 12:52:18.000000000","message":"nit: As this is related to concurrency and occurs only during the start - I\u0027d add an info level log here.","commit_id":"e9be452f6fdd2c1558eed29dac7d80de455cd0aa"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"6a7fb2c4bef8ba173c5a24aa343da814c7f4e5c7","unresolved":false,"context_lines":[{"line_number":61,"context_line":"            ovn_conf.get_ovn_sb_connection(),"},{"line_number":62,"context_line":"            self.sb_events).start("},{"line_number":63,"context_line":"                timeout\u003dovn_conf.get_ovn_ovsdb_timeout())"},{"line_number":64,"context_line":"        self._started.set()"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def stop(self):"},{"line_number":67,"context_line":"        if self._started.is_set():"}],"source_content_type":"text/x-python","patch_set":7,"id":"3353eb7d_dcf6ebaf","line":64,"in_reply_to":"e4ee7055_86d3e021","updated":"2026-05-14 15:34:16.000000000","message":"Done","commit_id":"e9be452f6fdd2c1558eed29dac7d80de455cd0aa"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"47501d34e8ee0d60e114f67ccc4149759a8c3634","unresolved":true,"context_lines":[{"line_number":84,"context_line":"        ]"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def full_sync(self):"},{"line_number":87,"context_line":"        self._started.wait()"},{"line_number":88,"context_line":"        if not self.nb_api.ovsdb_connection.idl.is_lock_contended:"},{"line_number":89,"context_line":"            LOG.info(\"Full BGP topology synchronization started\")"},{"line_number":90,"context_line":"            # First make sure all chassis are indexed"}],"source_content_type":"text/x-python","patch_set":7,"id":"7c70797d_c2961770","line":87,"updated":"2026-05-14 12:52:18.000000000","message":"And here too","commit_id":"e9be452f6fdd2c1558eed29dac7d80de455cd0aa"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"3ff19c1026969d5c061531c312f262881cfe2d17","unresolved":false,"context_lines":[{"line_number":84,"context_line":"        ]"},{"line_number":85,"context_line":""},{"line_number":86,"context_line":"    def full_sync(self):"},{"line_number":87,"context_line":"        self._started.wait()"},{"line_number":88,"context_line":"        if not self.nb_api.ovsdb_connection.idl.is_lock_contended:"},{"line_number":89,"context_line":"            LOG.info(\"Full BGP topology synchronization started\")"},{"line_number":90,"context_line":"            # First make sure all chassis are indexed"}],"source_content_type":"text/x-python","patch_set":7,"id":"aa47e4b3_1a9f9afc","line":87,"in_reply_to":"7c70797d_c2961770","updated":"2026-05-14 15:33:31.000000000","message":"Done","commit_id":"e9be452f6fdd2c1558eed29dac7d80de455cd0aa"}],"neutron/services/bgp/worker.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"8617dd9ef8f354ede6b4d41e1ad57392f83b80b6","unresolved":true,"context_lines":[{"line_number":20,"context_line":"class BGPWorker(worker.NeutronBaseWorker):"},{"line_number":21,"context_line":"    def __init__(self):"},{"line_number":22,"context_line":"        super().__init__(worker_process_count\u003d0)"},{"line_number":23,"context_line":"        self._reconciler \u003d None"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def start(self):"},{"line_number":26,"context_line":"        super().start(desc\u003d\"bgp worker\")"}],"source_content_type":"text/x-python","patch_set":1,"id":"d7676b7f_8fd2e96e","line":23,"range":{"start_line":23,"start_character":8,"end_line":23,"end_character":31},"updated":"2026-05-12 12:59:22.000000000","message":"If the problem is that this variable could not exist when stop is called, it should be declared before the `super().__init__` call.","commit_id":"aeb40378b1a13ec7979d0ff93d68ef2806d3fcc7"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"812ba7314e900d0c129574cd4a777fb239a5d5a9","unresolved":false,"context_lines":[{"line_number":20,"context_line":"class BGPWorker(worker.NeutronBaseWorker):"},{"line_number":21,"context_line":"    def __init__(self):"},{"line_number":22,"context_line":"        super().__init__(worker_process_count\u003d0)"},{"line_number":23,"context_line":"        self._reconciler \u003d None"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def start(self):"},{"line_number":26,"context_line":"        super().start(desc\u003d\"bgp worker\")"}],"source_content_type":"text/x-python","patch_set":1,"id":"7703861f_686c5d45","line":23,"range":{"start_line":23,"start_character":8,"end_line":23,"end_character":31},"in_reply_to":"d7676b7f_8fd2e96e","updated":"2026-05-12 13:11:13.000000000","message":"Done","commit_id":"aeb40378b1a13ec7979d0ff93d68ef2806d3fcc7"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"abffbfd08aeff06960f97887a9230c4705d05d03","unresolved":true,"context_lines":[{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class BGPWorker(worker.NeutronBaseWorker):"},{"line_number":21,"context_line":"    def __init__(self):"},{"line_number":22,"context_line":"        self._reconciler \u003d None"},{"line_number":23,"context_line":"        super().__init__(worker_process_count\u003d0)"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def start(self):"}],"source_content_type":"text/x-python","patch_set":2,"id":"9c927b42_84253abe","line":22,"updated":"2026-05-12 17:44:15.000000000","message":"we briefly talked about this on Slack. How about we create the Reconciler() here and implement a start() method, that creates the IDLs.\n\nThen we\u0027d always have the reconciler and the stop() would stop the IDLs only if they existed. This would bring the logic more the the reconciler rather than the worker object.","commit_id":"40b0d1349fb5288771546a839f6d2a9ae8c54838"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"797d04de4102fd46d637e68154a205ac6ad3b859","unresolved":true,"context_lines":[{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class BGPWorker(worker.NeutronBaseWorker):"},{"line_number":21,"context_line":"    def __init__(self):"},{"line_number":22,"context_line":"        self._reconciler \u003d None"},{"line_number":23,"context_line":"        super().__init__(worker_process_count\u003d0)"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def start(self):"}],"source_content_type":"text/x-python","patch_set":2,"id":"fc7394a6_7692ca4a","line":22,"in_reply_to":"9c927b42_84253abe","updated":"2026-05-13 08:11:06.000000000","message":"That could make sense too. In fact, having the idl instantiation and connection in the `BGPTopologyReconciler.__init__` method is not correct. The initialization of the idl connections should be done, as you stated, in a start method, after the initialization.","commit_id":"40b0d1349fb5288771546a839f6d2a9ae8c54838"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"42d285f35de5c43f511a13cc9dce063e956c3a09","unresolved":false,"context_lines":[{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class BGPWorker(worker.NeutronBaseWorker):"},{"line_number":21,"context_line":"    def __init__(self):"},{"line_number":22,"context_line":"        self._reconciler \u003d None"},{"line_number":23,"context_line":"        super().__init__(worker_process_count\u003d0)"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def start(self):"}],"source_content_type":"text/x-python","patch_set":2,"id":"5d993fe2_0ff0db1c","line":22,"in_reply_to":"cad828b2_03cb19d8","updated":"2026-05-14 18:46:58.000000000","message":"Done","commit_id":"40b0d1349fb5288771546a839f6d2a9ae8c54838"},{"author":{"_account_id":31291,"name":"Eduardo Olivares","email":"eolivare@redhat.com","username":"eolivare"},"change_message_id":"09a9e3c452f1832e6c6651c02a5614b485b81216","unresolved":true,"context_lines":[{"line_number":19,"context_line":""},{"line_number":20,"context_line":"class BGPWorker(worker.NeutronBaseWorker):"},{"line_number":21,"context_line":"    def __init__(self):"},{"line_number":22,"context_line":"        self._reconciler \u003d None"},{"line_number":23,"context_line":"        super().__init__(worker_process_count\u003d0)"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def start(self):"}],"source_content_type":"text/x-python","patch_set":2,"id":"cad828b2_03cb19d8","line":22,"in_reply_to":"fc7394a6_7692ca4a","updated":"2026-05-13 13:54:31.000000000","message":"done, right?","commit_id":"40b0d1349fb5288771546a839f6d2a9ae8c54838"}]}
