From 8eceae1c1f10206eabbccb6ecbf3db39097fe04b Mon Sep 17 00:00:00 2001 From: Jordan Frazier <122494242+jordanrfrazier@users.noreply.github.com> Date: Wed, 8 Apr 2026 15:59:59 -0400 Subject: [PATCH] fix: remove retries on connection verification (#12568) * Remove retries on connection failures, shorten timeouts Faster notice to user on credential failures * set var in place * [autofix.ci] apply automated fixes --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> --- .../deployment/watsonx_orchestrate/client.py | 15 ++++++--- .../deployment/test_watsonx_orchestrate.py | 14 +++++++++ .../use-post-provider-account.test.ts | 31 +++++++++++++------ .../use-post-provider-account.ts | 1 + 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/src/backend/base/langflow/services/adapters/deployment/watsonx_orchestrate/client.py b/src/backend/base/langflow/services/adapters/deployment/watsonx_orchestrate/client.py index bbb028f342..cc4a303b79 100644 --- a/src/backend/base/langflow/services/adapters/deployment/watsonx_orchestrate/client.py +++ b/src/backend/base/langflow/services/adapters/deployment/watsonx_orchestrate/client.py @@ -128,12 +128,17 @@ def set_request_context_provider_clients(*, provider_id: UUID, user_id: UUID | s def get_authenticator(instance_url: str, api_key: str) -> IAMAuthenticator | MCSPAuthenticator: """Return the appropriate authenticator for the Watsonx Orchestrate API.""" if ".cloud.ibm.com" in instance_url: - return IAMAuthenticator(apikey=api_key, url=WxOAuthURL.IBM_IAM.value) - elif ".ibm.com" in instance_url: # noqa: RET505 - explicitness - return MCSPAuthenticator(apikey=api_key, url=WxOAuthURL.MCSP.value) + authenticator = IAMAuthenticator(apikey=api_key, url=WxOAuthURL.IBM_IAM.value) + elif ".ibm.com" in instance_url: + authenticator = MCSPAuthenticator(apikey=api_key, url=WxOAuthURL.MCSP.value) + else: + msg = f"Could not determine authentication scheme for instance URL: {instance_url}" + raise AuthSchemeError(message=msg) - msg = f"Could not determine authentication scheme for instance URL: {instance_url}" - raise AuthSchemeError(message=msg) + # Use a split (connect, read) timeout so that cold-start TCP/TLS handshakes + # fail fast instead of blocking for the SDK's default 60 s. + authenticator.token_manager.http_config = {"timeout": (10, 30)} + return authenticator async def resolve_wxo_client_credentials( diff --git a/src/backend/tests/unit/services/deployment/test_watsonx_orchestrate.py b/src/backend/tests/unit/services/deployment/test_watsonx_orchestrate.py index 04b1a6eec6..cf9280ff04 100644 --- a/src/backend/tests/unit/services/deployment/test_watsonx_orchestrate.py +++ b/src/backend/tests/unit/services/deployment/test_watsonx_orchestrate.py @@ -4976,6 +4976,20 @@ def test_get_authenticator_unknown_url(): get_authenticator("https://example.com", "test-key") +def test_get_authenticator_sets_http_timeout_on_iam(): + from langflow.services.adapters.deployment.watsonx_orchestrate.client import get_authenticator + + auth = get_authenticator("https://api.region-foobar.cloud.ibm.com", "test-key") + assert auth.token_manager.http_config == {"timeout": (10, 30)} + + +def test_get_authenticator_sets_http_timeout_on_mcsp(): + from langflow.services.adapters.deployment.watsonx_orchestrate.client import get_authenticator + + auth = get_authenticator("https://api.wxo.ibm.com", "test-key") + assert auth.token_manager.http_config == {"timeout": (10, 30)} + + def test_get_authenticator_uses_default_iam_urls_when_unset(monkeypatch): try: with monkeypatch.context() as context: diff --git a/src/frontend/src/controllers/API/queries/deployment-provider-accounts/__tests__/use-post-provider-account.test.ts b/src/frontend/src/controllers/API/queries/deployment-provider-accounts/__tests__/use-post-provider-account.test.ts index dfa619ab05..52a76b53b0 100644 --- a/src/frontend/src/controllers/API/queries/deployment-provider-accounts/__tests__/use-post-provider-account.test.ts +++ b/src/frontend/src/controllers/API/queries/deployment-provider-accounts/__tests__/use-post-provider-account.test.ts @@ -12,18 +12,22 @@ jest.mock("@/controllers/API/helpers/constants", () => ({ getURL: jest.fn(() => "/api/v1/deployments/providers"), })); +const mockMutate = jest.fn( + // biome-ignore lint/suspicious/noExplicitAny: test mock + (_key: any, fn: any, options: any) => ({ + // biome-ignore lint/suspicious/noExplicitAny: test mock + mutate: async (payload: any) => { + const result = await fn(payload); + options?.onSuccess?.(result); + options?.onSettled?.(result); + return result; + }, + }), +); + jest.mock("@/controllers/API/services/request-processor", () => ({ UseRequestProcessor: jest.fn(() => ({ - // biome-ignore lint/suspicious/noExplicitAny: test mock - mutate: jest.fn((_key: any, fn: any, options: any) => ({ - // biome-ignore lint/suspicious/noExplicitAny: test mock - mutate: async (payload: any) => { - const result = await fn(payload); - options?.onSuccess?.(result); - options?.onSettled?.(result); - return result; - }, - })), + mutate: mockMutate, queryClient: mockQueryClient, })), })); @@ -76,6 +80,13 @@ describe("usePostProviderAccount", () => { }); }); + it("disables automatic retries", () => { + usePostProviderAccount(); + + const options = mockMutate.mock.calls[0][2]; + expect(options.retry).toBe(0); + }); + it("returns created provider account", async () => { const created = { id: "prov-1", diff --git a/src/frontend/src/controllers/API/queries/deployment-provider-accounts/use-post-provider-account.ts b/src/frontend/src/controllers/API/queries/deployment-provider-accounts/use-post-provider-account.ts index 455d3a858d..e8174403f4 100644 --- a/src/frontend/src/controllers/API/queries/deployment-provider-accounts/use-post-provider-account.ts +++ b/src/frontend/src/controllers/API/queries/deployment-provider-accounts/use-post-provider-account.ts @@ -32,6 +32,7 @@ export const usePostProviderAccount: useMutationFunctionType< return mutate(["usePostProviderAccount"], fn, { ...options, + retry: 0, onSuccess: () => { return queryClient.refetchQueries({ queryKey: ["useGetProviderAccounts"],