Fix settings changes not taking effect until the poll interval elapsed

config.update_screen_settings() writes to config.json immediately, but
each screen's cached check() result only gets refreshed on its own
poll_interval (30 min for weather by default). So e.g. changing
Weather's forecast_days from 3 to 5 saved correctly but kept showing
the old 3-day forecast for up to 30 minutes, since the cached state
was fetched under the old setting and nothing told the scheduler to
re-check sooner.

Added Scheduler.invalidate_screen(), called from every settings route
right after config.update_screen_settings() succeeds, which resets
that screen's cache timestamp so the very next tick re-checks instead
of reusing stale data. Reproduced the bug and verified the fix with a
direct Scheduler unit test, then confirmed end-to-end through a real
running app (POST forecast_days=5, saw it render 5 days within the
next ~5s tick instead of after 30 minutes).
This commit is contained in:
Honey committed 2026-07-23 12:24:12 +02:00
1 parent 32c98cec16
commit 79641914fd
2 files changed
+21

No files matched your search

+9
View File
@@ -55,6 +55,7 @@ def create_app(config, screens: dict, scheduler) -> Flask:
"boost_cover": "boost_cover" in request.form,
"grayscale_cover": "grayscale_cover" in request.form,
})
scheduler.invalidate_screen("navidrome")
return redirect(url_for("settings_navidrome", saved=1))
return render_template("settings_navidrome.html", settings=config.get_screen_settings("navidrome"))
@@ -92,6 +93,7 @@ def create_app(config, screens: dict, scheduler) -> Flask:
"update_minutes": update_minutes,
**display_toggles,
})
scheduler.invalidate_screen("weather")
return redirect(url_for("settings_weather", saved=1))
else:
config.update_screen_settings("weather", {
@@ -102,6 +104,7 @@ def create_app(config, screens: dict, scheduler) -> Flask:
"update_minutes": update_minutes,
**display_toggles,
})
scheduler.invalidate_screen("weather")
return redirect(url_for("settings_weather", saved=1))
return render_template("settings_weather.html", settings=config.get_screen_settings("weather"), error=error)
@@ -131,9 +134,11 @@ def create_app(config, screens: dict, scheduler) -> Flask:
"results": results,
"update_minutes": update_minutes,
})
scheduler.invalidate_screen("departures")
return redirect(url_for("settings_departures", found=found["name"]))
else:
config.update_screen_settings("departures", {"results": results, "update_minutes": update_minutes})
scheduler.invalidate_screen("departures")
return redirect(url_for("settings_departures", saved=1))
return render_template("settings_departures.html", settings=config.get_screen_settings("departures"), error=error)
@@ -188,6 +193,7 @@ def create_app(config, screens: dict, scheduler) -> Flask:
if not error:
config.update_screen_settings("journey", updates)
scheduler.invalidate_screen("journey")
found_parts = [v for k, v in (("origin", origin_query), ("destination", destination_query)) if v]
if found_parts:
current = config.get_screen_settings("journey")
@@ -236,13 +242,16 @@ def create_app(config, screens: dict, scheduler) -> Flask:
"uploaded_filename": dest.name,
**common_updates,
})
scheduler.invalidate_screen("picture")
return redirect(url_for("settings_picture", saved=1))
elif url:
config.update_screen_settings("picture", {"mode": "url", "image_url": url, **common_updates})
scheduler.invalidate_screen("picture")
return redirect(url_for("settings_picture", saved=1))
else:
# Neither a new upload nor a URL change -- just update fit/boost/grayscale.
config.update_screen_settings("picture", common_updates)
scheduler.invalidate_screen("picture")
return redirect(url_for("settings_picture", saved=1))
return render_template("settings_picture.html", settings=config.get_screen_settings("picture"), error=error)