diff options
| author | Craig Jennings <c@cjennings.net> | 2026-06-30 17:42:21 -0400 |
|---|---|---|
| committer | Craig Jennings <c@cjennings.net> | 2026-06-30 17:42:21 -0400 |
| commit | 610fe106ad07ecc603c5c8badb11d38ce62c4c9c (patch) | |
| tree | b932d424e9ffbbcd14a641ecf3dfa3c8059ebf1c /modules/calendar-sync-source.el | |
| parent | dc2784b6c271bf7733259a1d5cd3657485ef7b1b (diff) | |
| download | dotemacs-610fe106ad07ecc603c5c8badb11d38ce62c4c9c.tar.gz dotemacs-610fe106ad07ecc603c5c8badb11d38ce62c4c9c.zip | |
fix(calendar-sync): skip overlapping syncs for the same calendar
A timer tick that fired while a calendar's previous fetch was still running launched a second concurrent sync for that calendar, wasting work and racing to write the same org file. The dispatcher now skips a calendar whose status is already syncing and logs the skipped tick.
The sentinel resets the status on process exit, so the skip clears on its own. load-state also clears a stale syncing status left by a crash, so a calendar can't be skipped forever.
Diffstat (limited to 'modules/calendar-sync-source.el')
| -rw-r--r-- | modules/calendar-sync-source.el | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/modules/calendar-sync-source.el b/modules/calendar-sync-source.el index d9efc885..15c91c59 100644 --- a/modules/calendar-sync-source.el +++ b/modules/calendar-sync-source.el @@ -90,7 +90,13 @@ Hash table mapping calendar name (string) to state plist with: (let ((cal-states (alist-get 'calendar-states state))) (clrhash calendar-sync--calendar-states) (dolist (entry cal-states) - (puthash (car entry) (cdr entry) calendar-sync--calendar-states))))) + (let ((st (cdr entry))) + ;; A persisted `syncing' status is stale in a fresh process + ;; (no sync is actually running), so reset it; otherwise the + ;; in-flight guard would skip that calendar forever. + (when (eq (plist-get st :status) 'syncing) + (setq st (plist-put (copy-sequence st) :status 'never))) + (puthash (car entry) st calendar-sync--calendar-states)))))) (error (calendar-sync--log-silently "calendar-sync: Error loading state: %s" (error-message-string err)))))) @@ -98,6 +104,13 @@ Hash table mapping calendar name (string) to state plist with: "Get state plist for CALENDAR-NAME, or nil if not found." (gethash calendar-name calendar-sync--calendar-states)) +(defun calendar-sync--syncing-p (calendar-name) + "Return non-nil when CALENDAR-NAME has an in-flight sync. +Used to skip an overlapping sync when a timer tick fires while the previous +sync for the same calendar is still running." + (eq (plist-get (calendar-sync--get-calendar-state calendar-name) :status) + 'syncing)) + (defun calendar-sync--set-calendar-state (calendar-name state) "Set STATE plist for CALENDAR-NAME." (puthash calendar-name state calendar-sync--calendar-states)) |
