Improve SmartHomeMonitorWatcherTask: CancellationToken propagation, sync, and logging#60
Conversation
…, logging improvements Co-authored-by: thomasneuberger <23504477+thomasneuberger@users.noreply.github.com> Agent-Logs-Url: https://github.com/thomasneuberger/TgHomeBot/sessions/02041d09-0799-491d-ac3a-ccd36acdea63
0e08a63
into
Feature/SmartHomeMonitorWatcher
There was a problem hiding this comment.
Pull request overview
This PR refines the Smart Home monitor “watchdog” flow by propagating cancellation tokens through the connector API, synchronizing monitor start checks to avoid races, and reducing log noise in the scheduled watcher task.
Changes:
- Updated
ISmartHomeConnector.EnsureMonitorIsRunningto accept aCancellationToken. - Improved
HomeAssistantConnector.EnsureMonitorIsRunningto propagate cancellation, handleUnknownstate likeIdle, and synchronize access with a semaphore. - Updated
SmartHomeMonitorWatcherTaskto honor cancellation early, pass the token through, and adjust logging levels (success → Debug, failure → Warning).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| TgHomeBot.SmartHome.HomeAssistant/HomeAssistantConnector.cs | Adds token-aware, semaphore-synchronized monitor “ensure running” logic and treats Unknown as startable. |
| TgHomeBot.SmartHome.Contract/ISmartHomeConnector.cs | Updates connector contract to include cancellation in EnsureMonitorIsRunning. |
| TgHomeBot.Scheduling/Tasks/SmartHomeMonitorWatcherTask.cs | Propagates cancellation and adjusts logging to be less noisy on success. |
Comments suppressed due to low confidence (1)
TgHomeBot.SmartHome.HomeAssistant/HomeAssistantConnector.cs:98
- The broad
catch (Exception)here will also catchOperationCanceledExceptionfrom_semaphore.WaitAsync(cancellationToken)/StartMonitoringAsync(cancellationToken), log it as an error, and returnfalse. That breaks cancellation propagation (e.g., scheduler shutdown) and can cause spurious warning/error logs. HandleOperationCanceledExceptionseparately (rethrow whencancellationToken.IsCancellationRequested) and only log/return false for non-cancellation failures.
catch (Exception e)
{
logger.LogError(e, "Error ensuring Home Assistant monitor is running");
return false;
}
| await _semaphore.WaitAsync(cancellationToken); | ||
| try | ||
| { | ||
| switch (_smartHomeMonitor?.State) | ||
| { | ||
| case MonitorState.Idle: | ||
| case MonitorState.Unknown: | ||
| await _smartHomeMonitor!.StartMonitoringAsync(cancellationToken); | ||
| return true; |
There was a problem hiding this comment.
StartMonitoringAsync can perform network I/O and retry loops (potentially taking a long time). Because it is awaited while holding _semaphore, other callers that need the same semaphore (e.g., CreateMonitorAsync used by /check via GetMonitorStateRequestHandler) can be blocked for the entire connection/retry duration. Consider limiting the semaphore scope to just reading _smartHomeMonitor/State and deciding whether to start, then call StartMonitoringAsync outside the lock (it’s already idempotent when the WebSocket is open).
* Add SmartHomeMonitorWatcherTask * Improve SmartHomeMonitorWatcherTask: CancellationToken propagation, sync, and logging (#60) * Initial plan * Apply PR review feedback: CancellationToken, Unknown state, semaphore, logging improvements Co-authored-by: thomasneuberger <23504477+thomasneuberger@users.noreply.github.com> Agent-Logs-Url: https://github.com/thomasneuberger/TgHomeBot/sessions/02041d09-0799-491d-ac3a-ccd36acdea63 --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: thomasneuberger <23504477+thomasneuberger@users.noreply.github.com> --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Addresses review feedback on the
SmartHomeMonitorWatcherTaskPR: missing cancellation support, race conditions inEnsureMonitorIsRunning, unhandledUnknownstate, and noisy logging.Changes
ISmartHomeConnector—EnsureMonitorIsRunningnow accepts aCancellationTokenHomeAssistantConnector.EnsureMonitorIsRunningCancellationTokeninstead ofCancellationToken.NoneMonitorState.UnknownlikeIdle— attemptsStartMonitoringAsyncrather than silently returningfalse_semaphoreto prevent races withCreateMonitorAsyncSmartHomeMonitorWatcherTask.ExecuteAsynccancellationToken.ThrowIfCancellationRequested()before workcancellationTokenthrough to the connectorInformation→Debug; usesWarningon failure🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.