Skip to content

feat: on-demand refresh — reload service + auto-refresh on container events#211

Open
lebdim wants to merge 1 commit into
ualex73:masterfrom
lebdim:feature/reload-service
Open

feat: on-demand refresh — reload service + auto-refresh on container events#211
lebdim wants to merge 1 commit into
ualex73:masterfrom
lebdim:feature/reload-service

Conversation

@lebdim

@lebdim lebdim commented Jul 8, 2026

Copy link
Copy Markdown

Summary

Two related improvements that make monitor_docker data update on demand instead of only every scan_interval:

  1. New monitor_docker.reload service — force an immediate refresh of all monitored Docker data (container state, stats and engine info).
  2. Auto-refresh on container events — the Docker event stream now triggers an immediate refresh on start/stop/die/kill/pause/unpause/restart.

Motivation

The sensors are push-based (should_poll=False) and the background poll loops await asyncio.sleep(scan_interval) between fetches, so there was previously no way to refresh on demand short of restarting Home Assistant (homeassistant.update_entity is a no-op on these entities). Also, _run_docker_events only acted on create/destroy/rename and merely logged start/stop, so a plain start/stop was reflected only on the next poll.

This is useful for:

  • Dashboards/automations that need up-to-date container state right after an action.
  • Setups that raise scan_interval (to reduce recorder churn) but still want a manual "Refresh now" button and instant reaction to start/stop.

Note: the reload service registration was already stubbed out in the code (commented async_setup_reload_service + an empty async_reset_platform). This implements it via a lightweight refresh rather than a full platform reload.

Implementation

  • A shared asyncio.Event per DockerAPI, passed to each DockerContainerAPI. The plain interval asyncio.sleep(self._interval) in both the docker-info loop and each container loop is replaced by _sleep_or_refresh() = asyncio.wait_for(event.wait(), timeout=interval).
  • request_refresh() does event.set() + event.clear(), waking every current waiter exactly once so they fetch immediately and push fresh values to the existing entities (no teardown/re-add; entity IDs and history preserved).
  • The monitor_docker.reload service calls request_refresh() on every configured instance.
  • _run_docker_events now calls request_refresh() on container start/stop/die/kill/pause/unpause/restart actions.
  • Retry sleeps are untouched; the container loop falls back to a plain sleep when no event is provided (backwards-compatible).

Testing

Live Docker host (25 containers, scan_interval: 60, allinone):

  • monitor_docker.reload appears in Developer Tools → Actions; calling it refreshes container sensors within ~1s (verified a container's CPU% changing off-cycle) vs. no change without it.
  • Starting/stopping a container triggers an immediate refresh via the event stream.
  • No teardown; entities and history intact; no errors in the log.

@lebdim

lebdim commented Jul 8, 2026

Copy link
Copy Markdown
Author

cc @ualex73 — this implements the monitor_docker.reload service that was previously stubbed out (the commented async_setup_reload_service + empty async_reset_platform). It uses a lightweight on-demand refresh (shared asyncio.Event waking the poll loops) rather than a full platform reload, so entities/history are preserved. Happy to adjust naming or approach if you'd prefer. Thanks for the integration!

@lebdim lebdim changed the title feat: add monitor_docker.reload service for on-demand refresh feat: on-demand refresh — reload service + auto-refresh on container events Jul 8, 2026
@lebdim lebdim force-pushed the feature/reload-service branch from 7e95fc8 to 3e4b583 Compare July 8, 2026 08:16
…events

Add a `monitor_docker.reload` service and make the Docker event stream
trigger an immediate refresh, so monitored data updates on demand instead
of only every scan_interval.

The sensors are push-based (should_poll=False) and the background poll
loops sleep for scan_interval between fetches, so previously there was no
way to refresh on demand short of restarting Home Assistant
(homeassistant.update_entity is a no-op on these entities). In addition,
_run_docker_events only acted on create/destroy/rename and merely logged
start/stop/health, so those were reflected only on the next poll.

Implementation:
- Each poll loop (the docker-info loop and every container loop) owns an
  asyncio.Event and waits on it via asyncio.wait_for in place of the plain
  interval sleep, clearing it after every wake. request_refresh() sets the
  events; because each loop clears its own event, a request is never lost
  even if a loop is mid-fetch when it arrives (e.g. the rapid die+start of
  a container restart).
- A new monitor_docker.reload service calls request_refresh() on every
  configured instance.
- _run_docker_events calls request_refresh() on container start/stop/die/
  kill/oom/pause/unpause/restart and health_status events, so any state or
  health change from any source (HA switch, CLI, Portainer, Watchtower, ...)
  refreshes immediately. This also allows raising scan_interval to reduce
  recorder churn without losing responsiveness.
- Existing entities are reused (no teardown/re-add); entity IDs and history
  are preserved. Retry sleeps are left untouched.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@lebdim lebdim force-pushed the feature/reload-service branch from 3e4b583 to 28ad386 Compare July 8, 2026 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant