Always Log the Process Summary and Handle Stop Signals#789
Merged
Conversation
Force the end-of-run summary (ProcessDriver counts and DeleteEmptyFolders) at information level so it survives --logwarning. Handle SIGINT, SIGTERM, and SIGQUIT so a stop (docker stop, Ctrl+C) cancels processing gracefully and logs the summary and exit code before exit, instead of being force-killed (exit 143). Replace the Console.CancelKeyPress and custom Ctrl+Q/Ctrl+Z key handlers with one PosixSignalRegistration path.
There was a problem hiding this comment.
Pull request overview
Ensures PlexCleaner always emits an end-of-run summary (even under --logwarning) and cancels gracefully on stop signals so processing can unwind and still log the summary + exit code before exit (especially relevant for Docker/monitor scenarios).
Changes:
- Force end-of-run summary lines to bypass the warning-only floor via
LogOverrideContext(). - Replace custom key-based cancellation with POSIX signal handling (
SIGINT/SIGTERM/SIGQUIT) to drive a unified graceful-cancel path. - Document Docker stop grace guidance (
stop_grace_period/docker stop --time) so long encodes have time to unwind beforeSIGKILL.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| README.md | Adds release note + Docker stop grace guidance for monitor usage. |
| HISTORY.md | Adds changelog entries for forced summaries and signal-based graceful interruption. |
| PlexCleaner/Program.cs | Registers termination signal handlers and logs exit code using forced logging. |
| PlexCleaner/ProcessDriver.cs | Forces task summary logs (completed/time/counts) to survive --logwarning. |
| PlexCleaner/Process.cs | Forces deleted-folder summary log to survive --logwarning. |
| PlexCleaner/Monitor.cs | Removes the old interrupt-message console prompt from monitor startup logging. |
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.
What
When the Docker container runs
monitor --preprocess --logwarningand is stopped(
docker stop= SIGTERM), no end-of-run summary was written: the process wasforce-killed (exit 143) before logging, and part of the summary was suppressed by the
warning floor anyway. This makes every processing run always log its summary, and makes
any stop signal interrupt processing gracefully and still log the summary + exit code
before exiting.
How
ProcessDriver.ProcessFiles(Completed / Processing time /Total files / Error files) and
DeleteEmptyFoldersnow log viaLogOverrideContext()so they survive
--logwarning, matching the already-forcedProcess.ProcessFilescounts and
Exit Code. Covers theprocessverb, the monitor preprocess pass and eachbatch, and the standalone verbs (one
ProcessFilesfunnel).PosixSignalRegistrationforSIGINT,SIGTERM, andSIGQUIT, all routed to one handler that setscontext.Cancel = trueand cancels theshared token. On any signal, processing unwinds (in-flight ffmpeg/HandBrake already abort
via the cancel token), the forced summary runs, and Main logs
Exit Codeand flushes.This replaces the
Console.CancelKeyPresshandler and the customCtrl+Q/Ctrl+Zkeyreader with a single consistent path (the custom keys are removed).
The command invocation stays synchronous. Confirmed against the System.CommandLine 2.0.9
source (
InvocationPipeline.cs): the syncInvokepath constructs noProcessTerminationHandlerand registers no signal handlers, so self-managing signals isconflict-free (
ProcessTerminationTimeoutonly applies toInvokeAsync).Testing
--logwarning:processlogs the full forced summary (Completed/Total/Error/Modified/VerifyFailed/Deleted folders/Exit Code).
SIGINT/SIGTERM/SIGQUITmid-run: logsOperation interrupted : <signal>+Exit Code : 0and exits 0 (graceful), not 143.dotnet test: 155 passed.Notes
Docs: added a
stop_grace_period/docker stop --timenote to the monitor section so along in-flight encode can unwind before SIGKILL. A full async-invocation conversion (the
maintainer's longer-term goal) is scoped separately and intentionally not part of this fix.