diff --git a/src/lfx/src/lfx/services/manager.py b/src/lfx/src/lfx/services/manager.py index 2401ac7d91..e07c947b1e 100644 --- a/src/lfx/src/lfx/services/manager.py +++ b/src/lfx/src/lfx/services/manager.py @@ -306,6 +306,12 @@ class ServiceManager: self.services = {} self.factories = {} + # ``teardown`` empties the factory registry, so the "registered" flag has + # to drop too: get_service() re-registers factories only when + # are_factories_registered() is False. Leaving it set after a teardown + # makes the next lookup skip re-registration and raise + # NoFactoryRegisteredError. + self.factory_registered = False @classmethod def get_factories(cls) -> list[ServiceFactory]: diff --git a/src/lfx/tests/unit/services/test_service_manager.py b/src/lfx/tests/unit/services/test_service_manager.py index c1b4e8b11b..a440f30634 100644 --- a/src/lfx/tests/unit/services/test_service_manager.py +++ b/src/lfx/tests/unit/services/test_service_manager.py @@ -359,6 +359,27 @@ class TestTeardown: # Services should be cleared assert ServiceType.STORAGE_SERVICE not in service_manager.services + @pytest.mark.asyncio + async def test_teardown_clears_factories_registered_flag(self, service_manager): + """teardown() must clear the factories-registered flag, not just the dict. + + get_service() (both lfx and langflow) re-registers factories only when + are_factories_registered() returns False. teardown() empties + self.factories, so if it leaves the flag set, every later lookup skips + re-registration and raises NoFactoryRegisteredError. That surfaced as + flow-execution 500s once Graph.arun routed through the executor service + and a sibling test had torn the global manager down. + """ + service_manager.register_service_class(ServiceType.STORAGE_SERVICE, LocalStorageService) + service_manager.get(ServiceType.STORAGE_SERVICE) + service_manager.set_factory_registered() + assert service_manager.are_factories_registered() is True + + await service_manager.teardown() + + assert service_manager.factories == {} + assert service_manager.are_factories_registered() is False + class TestConfigDirectorySource: """Tests for config_dir parameter with real services."""