Skip to content

Commit a550509

Browse files
wukathcopybara-github
authored andcommitted
fix: Update the retry_on_closed_resource decorator to retry on all errors
Retrying only on closed_resource error is not enough to be reliable for production environments due to the other network errors that may occur -- remote protocol error, read timeout, etc. We will update this to retry on all errors. Since it is only a one-time retry, it should not affect latency significantly. Fixes #2561. Co-authored-by: Kathy Wu <wukathy@google.com> PiperOrigin-RevId: 831123085
1 parent d85a301 commit a550509

File tree

4 files changed

+17
-17
lines changed

4 files changed

+17
-17
lines changed

src/google/adk/tools/mcp_tool/mcp_session_manager.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -108,10 +108,10 @@ class StreamableHTTPConnectionParams(BaseModel):
108108
terminate_on_close: bool = True
109109

110110

111-
def retry_on_closed_resource(func):
112-
"""Decorator to automatically retry action when MCP session is closed.
111+
def retry_on_errors(func):
112+
"""Decorator to automatically retry action when MCP session errors occur.
113113
114-
When MCP session was closed, the decorator will automatically retry the
114+
When MCP session errors occur, the decorator will automatically retry the
115115
action once. The create_session method will handle creating a new session
116116
if the old one was disconnected.
117117
@@ -126,11 +126,11 @@ def retry_on_closed_resource(func):
126126
async def wrapper(self, *args, **kwargs):
127127
try:
128128
return await func(self, *args, **kwargs)
129-
except (anyio.ClosedResourceError, anyio.BrokenResourceError):
130-
# If the session connection is closed or unusable, we will retry the
131-
# function to reconnect to the server. create_session will handle
132-
# detecting and replacing disconnected sessions.
133-
logger.info('Retrying %s due to closed resource', func.__name__)
129+
except Exception as e:
130+
# If an error is thrown, we will retry the function to reconnect to the
131+
# server. create_session will handle detecting and replacing disconnected
132+
# sessions.
133+
logger.info('Retrying %s due to error: %s', func.__name__, e)
134134
return await func(self, *args, **kwargs)
135135

136136
return wrapper

src/google/adk/tools/mcp_tool/mcp_tool.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
from ...agents.readonly_context import ReadonlyContext
3333
from .._gemini_schema_util import _to_gemini_schema
3434
from .mcp_session_manager import MCPSessionManager
35-
from .mcp_session_manager import retry_on_closed_resource
35+
from .mcp_session_manager import retry_on_errors
3636

3737
# Attempt to import MCP Tool from the MCP library, and hints user to upgrade
3838
# their Python version to 3.10 if it fails.
@@ -184,7 +184,7 @@ async def run_async(
184184
return {"error": "This tool call is rejected."}
185185
return await super().run_async(args=args, tool_context=tool_context)
186186

187-
@retry_on_closed_resource
187+
@retry_on_errors
188188
@override
189189
async def _run_async_impl(
190190
self, *, args, tool_context: ToolContext, credential: AuthCredential

src/google/adk/tools/mcp_tool/mcp_toolset.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
from ..tool_configs import BaseToolConfig
3838
from ..tool_configs import ToolArgsConfig
3939
from .mcp_session_manager import MCPSessionManager
40-
from .mcp_session_manager import retry_on_closed_resource
40+
from .mcp_session_manager import retry_on_errors
4141
from .mcp_session_manager import SseConnectionParams
4242
from .mcp_session_manager import StdioConnectionParams
4343
from .mcp_session_manager import StreamableHTTPConnectionParams
@@ -155,7 +155,7 @@ def __init__(
155155
self._auth_credential = auth_credential
156156
self._require_confirmation = require_confirmation
157157

158-
@retry_on_closed_resource
158+
@retry_on_errors
159159
async def get_tools(
160160
self,
161161
readonly_context: Optional[ReadonlyContext] = None,

tests/unittests/tools/mcp_tool/test_mcp_session_manager.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
# Import dependencies with version checking
3333
try:
3434
from google.adk.tools.mcp_tool.mcp_session_manager import MCPSessionManager
35-
from google.adk.tools.mcp_tool.mcp_session_manager import retry_on_closed_resource
35+
from google.adk.tools.mcp_tool.mcp_session_manager import retry_on_errors
3636
from google.adk.tools.mcp_tool.mcp_session_manager import SseConnectionParams
3737
from google.adk.tools.mcp_tool.mcp_session_manager import StdioConnectionParams
3838
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
@@ -44,7 +44,7 @@ class DummyClass:
4444
pass
4545

4646
MCPSessionManager = DummyClass
47-
retry_on_closed_resource = lambda x: x
47+
retry_on_errors = lambda x: x
4848
SseConnectionParams = DummyClass
4949
StdioConnectionParams = DummyClass
5050
StreamableHTTPConnectionParams = DummyClass
@@ -375,12 +375,12 @@ async def test_close_with_errors(self):
375375
assert "Close error 1" in error_output
376376

377377

378-
def test_retry_on_closed_resource_decorator():
379-
"""Test the retry_on_closed_resource decorator."""
378+
def test_retry_on_errors_decorator():
379+
"""Test the retry_on_errors decorator."""
380380

381381
call_count = 0
382382

383-
@retry_on_closed_resource
383+
@retry_on_errors
384384
async def mock_function(self):
385385
nonlocal call_count
386386
call_count += 1

0 commit comments

Comments
 (0)