Repository navigation
Conversation
…eased Signed-off-by: David Leong <leongdl@amazon.com>
|
Claude review · advisory Reviewed Open: 0 blocking · 0 should-fix · 0 nit. ✅ Nothing blocking. Fix or reply to each thread; the next revision's review re-checks open threads and resolves those it agrees are handled. Resolving a thread yourself also closes it. Later revisions review only what changed. |
…les open Signed-off-by: David Leong <leongdl@amazon.com>
| def _find_lock_holders(files: list[str]) -> tuple[list[tuple[int, str]], Optional[str]]: | ||
| """The (pid, name) of each process holding any of ``files`` open, and the | ||
| reason the lookup failed if it did. Windows only.""" | ||
| from ._win32._file_locks import processes_holding # type: ignore |
There was a problem hiding this comment.
Should fix: This lookup only feeds a log message, but a failure in it can abort cleanup. The import sits outside the try, and only OSError is caught. Importing _win32._file_locks runs ctypes.WinDLL("rstrtmgr") at module load, so if that DLL fails to load, an OSError escapes cleanup() before any retry. A ctypes.ArgumentError or anything else non-OSError from the Restart Manager calls escapes the same way. Session.cleanup only catches RuntimeError, so the remaining retries are skipped, _runner.shutdown() never runs, and the session never reaches ENDED. Move the import inside the try and catch Exception:
try:
from ._win32._file_locks import processes_holding
return [...], None
except Exception as err:
return [], str(err)There was a problem hiding this comment.
Fixed in efb2a73. The import is inside the try and it catches Exception, so a missing rstrtmgr.dll or a ctypes error becomes the "could not be determined: : " clause of the warning and the retries continue. New test test_a_lookup_that_cannot_even_import_does_not_abort_cleanup blocks the module import and checks that cleanup still retries and succeeds. It fails against e82c7d0.
There was a problem hiding this comment.
Addressed: The import now sits inside the try and the handler catches Exception, so a failed import or ctypes error becomes the reason string and cleanup retries continue. The new test covers this case.
Signed-off-by: David Leong <leongdl@amazon.com>
Signed-off-by: David Leong <leongdl@amazon.com>
Signed-off-by: David Leong <leongdl@amazon.com>
Fixes: no GitHub issue; reported against Windows workers running DCC applications.
What was the problem/requirement? (What/Why)
On Windows, session cleanup leaks the working directory when a process started by the job still has a file in it open. A child process can keep its handles after it exits or is terminated, and Windows will not delete a file while a handle to it is open.
TempDir.cleanupranrmtreeonce and raised:Nothing said which process held the file. On long-running workers these directories accumulate until the disk fills.
What was the solution? (How)
TempDir.cleanupretries the deletion after 1, 2, 4, 8 and 16 s (_CLEANUP_RETRY_DELAYS_SECONDS, about 31 s in total). POSIX does not retry, because a failure there is a permission problem that waiting will not fix. A directory that was already missing still raises immediately, as before.Session.cleanupnow passes it) naming the files that could not be deleted and the processes holding them open, found with the Restart Manager (RmGetList, new_win32/_file_locks.py), and the next delay or "Giving up.":RuntimeErroris unchanged.What is the impact of this change?
On Windows, cleanup blocks for up to about 31 s longer when a file is still held open, and logs a warning per failed attempt. The common case, where the first attempt succeeds, is unchanged. No change on POSIX.
TempDir.cleanupgains an optionalloggerargument.How was this change tested?
The test job leaves a detached grandchild process holding
locked.bin(opened with no sharing) in the session directory after the step exits. I ran it withopenjd runfromopenjd-climain on a Windows Server 2022 Deadline Cloud service-managed worker:Every warning named
powershell.exeand the grandchild's pid.TestCleanupRetryandTestCleanupLockLoggingcover the retry, the delays, the warning text with holders, a failed lookup, no lookup when only directories failed, nothing extra logged on POSIX, and the default logger. Windows-only tests hold a real file open, and one asserts the warning names this test's pid via the Restart Manager.sessions_v0960 passed. Windows: the tempdir tests pass; the fullsessions_v0suite has the same 28 failures on 0.14.0 and on this branch (wrap/resolved-symtab session-state tests, run as SYSTEM).ruff,black --checkandmypyare clean.Was this change documented?
Yes, in the docstrings on
TempDir.cleanupand_CLEANUP_RETRY_DELAYS_SECONDS.Is this a breaking change?
No.
Does this change impact security?
No. It deletes only the same paths as before. The Restart Manager query is read-only, and the log lines name files inside the session directory and the processes holding them.
Cross-port to openjd-rs
openjd-rs(link the PR here): fix(sessions): Retry TempDir cleanup on Windows and log cleanup failures openjd-rs#485, oropenjd-rsto port this change (link here): , orBy submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.