fix: close file handles via context manager in remaining call sites#98
Open
shaun0927 wants to merge 1 commit intolsdefine:mainfrom
Open
fix: close file handles via context manager in remaining call sites#98shaun0927 wants to merge 1 commit intolsdefine:mainfrom
shaun0927 wants to merge 1 commit intolsdefine:mainfrom
Conversation
Closes lsdefine#96. PR lsdefine#76 already converted the scheduler.py read site to a context manager. Apply the same treatment to the remaining unmanaged open() calls that this audit found across ga.py, agentmain.py, and frontends/wechatapp.py. Sites updated: ga.py - 23 : code_run header copy into the temp script - 387 : prepend-mode read of existing file in do_file_write - 388 : prepend-mode write of new+old back to disk - 424 : _check_plan_completion read of plan.md agentmain.py - 16 : tools_schema*.json load - 24 : global_mem.txt initial seed - 27-28: global_mem_insight.txt initial seed (was nested open(...).write(open(...).read()), so two leaks) - 33 : tmwebdriver cdp_bridge config.js seed - 105 : /session.<key> = <file> case (refactor 47f106c kept the unmanaged read) - 242 : reflect log append frontends/wechatapp.py - 183 : decrypted media bytes write to temp dir These match the pattern in lsdefine#48 ("multiple calls then model unresponsive, needs restart") for long-running adapters where GC of unreferenced file objects is delayed and FD limits matter. The launcher / startup-only sites are still affected because the same handler is reused in reflect-loop code paths. No behavior change: all reads/writes use the same modes, encodings, and bytes; only the file handle release timing changes.
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.
Closes #96.
Problem
PR #76 wrapped the scheduler's
open(...).read()in a context manager.Several similar patterns elsewhere still rely on garbage collection to
release the underlying file descriptor. For long-running daemons
(
tgapp.py,wechatapp.py,fsapp.py, etc.) the FD eventually leaksto the per-process limit and the symptom shown in #48 ("multiple
calls then model unresponsive, needs restart") becomes hard to
diagnose because the actual
EMFILEerror surfaces in some unrelatedlater open.
The recent refactor 47f106c also added a new unmanaged read at
agentmain.py:105(/session.<key> = <file>), which would have grownthe leak surface.
Fix
Convert the remaining unmanaged
open(...).<read|write>(...)patternsto
with open(...) as f:blocks. Same modes, encodings, bytes; only therelease timing changes.
ga.pyga.pydo_file_writega.py_check_plan_completionreadagentmain.pyagentmain.pyagentmain.pyagentmain.pyagentmain.py/session.<key>=<file>(added by 47f106c)agentmain.pyfrontends/wechatapp.pyVerification
Scope choices
the same idiomatic conversion at every site, and reviewing them in
one place makes it easy to confirm no behavior change.
agentmain.py:187-188is intentionally not changed — those fileobjects are owned by the subprocess for its lifetime and closing them
in the parent breaks the redirection.
if sys.stdout is None: sys.stdout = open(os.devnull, ...)at lines 3 and 5 is also unchanged because
sys.stdoutkeeps thereference alive for the entire process.
open(_logf, 'a', ...)at the wechatapp__main__block isunchanged for the same reason — the file is bound to
sys.stdoutfor the lifetime of the daemon.
Net diff: +21 / -11 lines, no functional change.