fix(scheduler): reload is unverifiable and unknown YAML sections vanish silently - #129
Open
mt-alarcon wants to merge 1 commit into
Open
Conversation
Both bugs share a shape: the scheduler knows something the operator needs and drops it on the floor. 1. SIGHUP reload is unverifiable. The two `[reload]` prints lack flush=True. stdout is normally redirected to a log file, so block buffering holds the lines indefinitely — in practice `[reload]` never appears in the log at all. Anyone checking "did my config reload?" reads an empty result and cannot tell a working reload from a broken one. The routine-execution prints already flush; only these two did not. 2. Unknown YAML sections vanish without a word. The loader reads exactly daily/weekly/monthly. Anything else — a typo, or a section a user assumed was supported — is dropped silently: those routines simply never run, with no error, no warning, nothing in the log. Now it warns and names the sections. Both were found on a live install: a config section had been sitting unread for weeks with routines under it, and a reload could not be confirmed even after it had in fact worked. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Reviewer's guide (collapsed on small PRs)Reviewer's GuideAdds explicit logging and validation around scheduler reloads and YAML configuration sections to make operator-facing behavior observable and debuggable, while keeping functional behavior unchanged except for new messages. Sequence diagram for YAML loader handling unknown sectionssequenceDiagram
participant Scheduler
participant YAMLConfig
Scheduler->>YAMLConfig: _load_routines_from_yaml(schedule, config_path, is_plugin)
YAMLConfig-->>Scheduler: config
Scheduler->>Scheduler: determine plugin_slug
Scheduler->>Scheduler: compute _unknown = [k for k in config if k not in _known_sections]
alt unknown_sections_present
Scheduler->>Scheduler: print(WARN unread section(s) ..., flush=True)
end
Scheduler->>Scheduler: iterate config.get(daily), config.get(weekly), config.get(monthly)
Sequence diagram for scheduler SIGHUP reload loggingsequenceDiagram
actor Operator
participant OS
participant Scheduler
Operator->>OS: send SIGHUP to scheduler
OS->>Scheduler: deliver SIGHUP
Scheduler->>Scheduler: shutdown(sig, frame)
Scheduler->>Scheduler: _reload_flag.is_set()
alt reload_flag_set
Scheduler->>Scheduler: print([reload] SIGHUP received ..., flush=True)
Scheduler->>Scheduler: schedule.clear()
Scheduler->>Scheduler: setup_schedule()
Scheduler->>Scheduler: total = len(schedule.get_jobs())
Scheduler->>Scheduler: print([reload] total routines scheduled, flush=True)
end
Scheduler->>Scheduler: schedule.run_pending()
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
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.
Two independent bugs in
scheduler.py, both the same shape: the scheduler knows something the operator needs and drops it silently.1. SIGHUP reload is unverifiable
No
flush=True. Since stdout is normally redirected to a log file, Python uses block buffering and these lines sit in the buffer indefinitely — in practice[reload]never appears in the log at all.The consequence is worse than a missing line. Someone checking "did my config reload?" sees nothing and cannot distinguish a working reload from a broken one. On our install this produced a real false conclusion in both directions: one person could not prove the reload had worked, and a second person read a pre-reload routine run as proof it had failed. The reload had worked all along; the evidence only surfaced when the process shut down and flushed its buffer.
The routine-execution print already passes
flush=True. Only these two did not.2. Unknown YAML sections vanish without a word
The loader reads exactly
daily,weekly,monthly. Any other top-level key — a typo, or a section someone assumed was supported — is dropped silently: the routines under it simply never run. No error, no warning, nothing in the log.We found a section that had been sitting unread for weeks with routines under it. Nothing in the system could have told us; it was found by reading the loader source.
Now the loader warns and names the offending sections. It does not add new sections or change what is read — it only stops the silence.
Scope
Deliberately minimal: two bug fixes, no new features, no behaviour change beyond the two messages. Both are running on a live install.
Related but not included, since it would be a feature rather than a fix: the monthly loop is hardcoded to day 1 / hour 8 and ignores any per-routine scheduling key. Upstream never advertised such a key, so that is a separate discussion.
Also available as a follow-up if wanted: a boot-time check that every scheduled routine's script actually exists, shouting on startup instead of failing once per tick forever. It caught four separate incidents downstream where a routine had never run once. It is left out here because our implementation leans on downstream-only alerting infrastructure and would need adapting.
🤖 Generated with Claude Code
Summary by Sourcery
Clarify scheduler behavior when reloading and reading YAML configuration so operators receive explicit feedback instead of silent failures.
Bug Fixes: