mirror of
https://github.com/dgtlmoon/changedetection.io.git
synced 2026-10-26 00:28:42 +00:00
Every watch carried its own copy of the 7-day schedule (15 nested dicts, ~30 strings),
about 3.7KiB of a ~7.6KiB watch, even though nearly every schedule is the untouched
default. At 40,000 watches that is ~146MB.
time_schedule_limit is now a slots + frozen pydantic dataclass (model/TimeScheduleLimit.py)
built on a small generic base (model/shared_defaults.py):
- Anything equal to the default is the one shared default instance, recursively, so an
untouched day or the whole default schedule costs nothing per watch.
- watch.json only stores what differs from the default (exclude_defaults), an enabled
schedule with default days is {"enabled": true}, a disabled custom week is kept.
- Frozen, so the shared default can never be mutated in place, assign a new value.
- Every write path (loading, edit form, API, clone) converts in watch_base __setitem__/update.
- Blank/None fields fall back per field, one empty value no longer loses the whole week.
- hours/minutes are ints, in the model, the form and the API spec (no upper bound,
multi-day windows are supported).
- The scheduler converts the global schedule once per pass instead of reading it per watch.
update_34 rewrites watch.json/tag.json compact and converts the global schedule's
"24"/"00" strings to ints.
Measured: 7.6KiB -> 3.9KiB per watch (296MiB -> 150MiB at 40k watches).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>