fix(integrations): close AsyncDaytona client in DaytonaEnvironment.close() - #6307
Closed
anxkhn wants to merge 1 commit into
Closed
fix(integrations): close AsyncDaytona client in DaytonaEnvironment.close()#6307anxkhn wants to merge 1 commit into
anxkhn wants to merge 1 commit into
Conversation
Collaborator
|
Hi @anxkhn , Thank you for your contribution! We appreciate you taking the time to submit this pull request. Can you please fix the failing ci mypy check tests before we can proceed with the review. |
anxkhn
force-pushed
the
fix/daytona-close-client
branch
from
July 9, 2026 17:12
62abbe0 to
bbb8e43
Compare
anxkhn
force-pushed
the
fix/daytona-close-client
branch
from
July 17, 2026 16:34
bbb8e43 to
e472c95
Compare
…ose() Await the AsyncDaytona client close method after deleting its sandbox so repeated environment lifecycles do not leak HTTP sessions. Verify that close is awaited exactly once. Signed-off-by: Anas Khan <83116240+anxkhn@users.noreply.github.com>
anxkhn
force-pushed
the
fix/daytona-close-client
branch
from
July 27, 2026 14:41
e472c95 to
f5b1904
Compare
Contributor
Author
|
rebased onto current main. the original pr-specific mypy failure remains fixed with the targeted no-untyped-call suppression required by the unannotated daytona sdk method; the current file-only mypy output is otherwise present on main as well. the focused tests pass (15 passed), and pre-commit passes on both changed files. @rohityan, could you please take another look? |
copybara-service Bot
pushed a commit
that referenced
this pull request
Jul 28, 2026
Merge #6307 PiperOrigin-RevId: 955513593
Collaborator
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
2. Or, if no issue exists, describe the change:
Problem:
DaytonaEnvironment.close()insrc/google/adk/integrations/daytona/_daytona_environment.pydeletes the sandbox and then drops theAsyncDaytonaclient by settingself._client = None, without awaiting the client'sclose():That client is an
AsyncDaytonainstance created in_create_sandbox(); it owns the underlying aiohttpClientSessionplus the REST and toolbox API clients. Just dropping the reference never releases those, so a socket/session leak accumulates on every create/close cycle. This matters for long-lived agents and for repeated test runs that set up and tear down an environment.The Daytona Python SDK documents that
AsyncDaytona.close()should be called to properly close the underlying HTTP sessions and avoid resource leaks (or the client can be used as an async context manager). The current code runs none of that.Solution:
Await
self._client.close()before clearing the reference, guarded on the client not beingNone:AsyncDaytona.close()is idempotent (it closes the API clients and the shared aiohttp session, all of which are no-ops when already closed), so the existing "secondclose()is a no-op" behavior is preserved.Testing Plan
Unit Tests:
The existing
test_close_deletes_sandbox_and_is_idempotenttest used aMagicMockclient and never asserted the client was closed, so it did not catch the leak. This PR gives the mock client anAsyncMockclose()and assertsDaytonaEnvironment.close()awaits it exactly once (and that it stays a no-op, still awaited only once, on a secondclose()).I confirmed the test actually guards the fix: with the production
await self._client.close()line removed, the updated test fails withAssertionError: Expected close to have been awaited once. Awaited 0 times.; with the fix in place it passes.pytestresults:No regressions in the wider integrations suite:
Manual End-to-End (E2E) Tests:
Not run. Exercising this path end to end requires a live Daytona account and API key to provision a real remote sandbox, which is not available in this environment. The change is confined to the client-teardown step of
close()and is covered by the unit test above.Checklist
Additional context
DaytonaEnvironmentis a recently added integration (feat(integrations): Add DaytonaEnvironment for remote sandbox workspaces, commitdf6baf4a). This is a small follow-up correctness fix to its teardown path.