Repository navigation
Close instruments when the daemon is done with them, not in __del__ - #99
Merged
Merged
Conversation
Instrument.__del__ called close(), which raises NotImplementedError in the base class and fails on an instrument that never connected. Exceptions in __del__ go to stderr, which a windowless daemon process doesn't have, and __del__ may never run at all for an instrument in a reference cycle. Now the daemon releases instruments deterministically: DaemonRunner closes every single-mode instance when it stops (also when it fails), and Daemon closes a session-mode instance when its client disconnects (LockableDaemon now chains to that). Instrument._release() calls close() at most once, skips classes without their own close(), and logs errors instead of raising them. __del__ remains a quiet last resort through the same path. Fixes #61 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Merged
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.
Fixes #61. This is independent of #98: no shared files, so they can merge in either order.
Problem
Instrument.__del__calledclose(), which caused three problems:close()raisesNotImplementedError, and many drivers'close()fails on an instrument that never connected (self.devicedoesn't exist).__del__go to stderr, and a daemon runs in a windowless child process, so nobody sees them.Change
DaemonRunner.runcloses every single-mode instance it created, throughDaemon.release_instruments(). This happens on the error path too.Daemon.clientDisconnectcloses that client's session-mode instances. Pyro discards them as soon as the connection closes anyway.LockableDaemon.clientDisconnectnow chains to it after releasing locks.Instrument._release()handles every call:close()at most once, so shutdown followed by garbage collection doesn't close an instrument twice;close();__del__remains a last resort through the same path, logging at debug level and never raising.close()docstring and CLAUDE.md now say whenclose()is called, and that it must cope with an instrument that never connected.Not covered: a session-mode instance whose client is still connected when the daemon stops. That still depends on
__del__, which is now harmless. Covering it would mean going through Pyro's internal connection list for each server type.Things to know
close()fails on an instrument that never connected (ppcl55x, the RTO, KDC101 and others) will log a warning at shutdown if their instrument was never connected. Before, that error went to an invisible stderr. Each of thoseclose()methods can be made tolerant in a later PR.Testing
test_service.py:_releasecloses an instrument once, leaves a class withoutclose()alone, and logs errors;__del__reports an unraisable exception.test_server.py, end to end over real sockets:DaemonandLockableDaemon;release_instruments().test_registration.py: a realDaemonRunnerwith an instrument in a reference cycle, and the garbage collector paused. Stopping the runner closes the instrument. On master it is never closed.🤖 Generated with Claude Code