-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: Add resource cleanup mechanism in CodeAgent #1056
base: main
Are you sure you want to change the base?
fix: Add resource cleanup mechanism in CodeAgent #1056
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. A comment below.
Do you think a test could be easily implemented?
src/smolagents/agents.py
Outdated
|
||
def cleanup(self): | ||
"""Clean up resources used by the agent, especially Docker container resources.""" | ||
if hasattr(self, "python_executor") and self.executor_type == "docker": |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the first condition is always True: self.python_executor
is defined at instantiation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, I'll remove the first condition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found that the first condition is necessary because there are some cases where the program exits before self.python_executor
is fully instantiated, and in those cases, CodeAgent
doesn't have the python_executor
attribute.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure of understanding your argument: if the program exits during instantiation, then the instance is not created, so self
does not exist, so you cannot delete a non-existing instance. 🤔
Am I missing something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. If CodeAgent
encounters an error during instantiation, the instance will still exist in an incomplete form and will still execute the logic in the __del__
method and cleanup
method. For example, if an error occurs when instantiating the docker executor, the CodeAgent
won't have a python_executor
attribute, but it will still execute CodeAgent.cleanup
. Without the if hasattr(self, "python_executor")
check, it would raise another error. I've already tested this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In an interactive console, several factors can affect the execution of the __del__
method:
- The Python interpreter may retain references to recently created objects, especially in an interactive environment.
- Even if the variable a goes out of scope, Python's garbage collector might not immediately reclaim the object. Garbage collection is typically triggered when the system needs more memory or after specific time intervals.
- In an interactive environment, the interpreter maintains special variables (such as _) that reference the results of recent expressions, potentially extending the object's lifecycle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see your point, @kingdomad, and I appreciate the discussion.
- I agree that we should not ignore the 1% of cases where
__del__
is reliably called. See my suggestion below. - At the same time, we also need to account for the other 99% of cases where
__del__
may not be called, ensuring proper resource cleanup in those scenarios. How do you think we could best handle this?
For the case where __del__
is called, I would suggest following the "Easier to ask for forgiveness than permission" approach, by wrapping the cleanup in a try
block:
try:
self.python_executor.delete()
except AttributeError:
pass
Let me know what you think!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You make a valid point, but I think you're making this more complicated than it needs to be. I've consulted both Claude 3.7 and GPT-4o, and they both agree with my approach to modifying the code! Which approach do you prefer? I'm happy to implement your suggestion if that's what you'd like!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@albertvillanova I've reconsidered, and your approach makes sense. I'll implement the change using the try-except pattern as you suggested.
Fix Docker Resource Leaks in CodeAgent
Added
cleanup()
and__del__()
methods toCodeAgent
class to properly release Docker container resources when the agent is destroyed. Otherwise, each timeCodeAgent
is used, Docker resources would need to be manually released.