Skip to content

Watch Mode

rhoopr edited this page May 3, 2026 · 13 revisions

Watch Mode

Watch mode runs kei as a long-lived process, repeating the download cycle at a fixed interval.

Usage

# Sync every hour
kei sync -u my@email.address -d /photos --watch-with-interval 3600

How It Works

After completing a full download pass (enumerate → filter → download), the process sleeps for the specified number of seconds, then starts a new pass. This repeats indefinitely until stopped by a shutdown signal (Ctrl+C, SIGTERM, or SIGHUP).

Each cycle checks for changes using a stored CloudKit syncToken. If nothing changed since the last cycle, the check completes in 1-2 API calls and the cycle ends immediately. When changes are detected, only the delta is downloaded. On the first cycle (no stored token), a full enumeration is performed. See State Tracking for details.

The minimum interval is 60 seconds. Values below 60 are rejected at startup. Apple rate-limits aggressively, and short intervals risk account lockouts.

Graceful Shutdown

Sending Ctrl+C, SIGTERM, or SIGHUP during a watch mode cycle will:

  1. Finish any in-flight downloads (partial .kei-tmp files are kept for resume)
  2. Skip remaining queued downloads
  3. Exit cleanly

If in-flight downloads don't finish within 30 seconds, they're cancelled and the process exits. If the signal arrives during the sleep interval between cycles, the sleep is interrupted and the process exits immediately. A second signal at any point force-exits the process.

Periodic Reconcile

--reconcile-every-n-cycles N (or [watch] reconcile_every_n_cycles = N) runs a reconcile pass every N watch cycles, catching files that were deleted from the download directory between syncs. The check is the same one kei reconcile runs by hand: any status = 'downloaded' row whose local_path no longer exists on disk is flipped to failed and re-downloaded on the next cycle.

Off by default. A common pairing is --watch-with-interval 3600 --reconcile-every-n-cycles 24 (hourly sync, daily reconcile).

Album Refresh

Albums are re-resolved at the start of each watch cycle. If you create a new album in iCloud, it will be discovered on the next cycle without restarting the daemon.

Error Tolerance

When a download cycle ends with partial failures (some files downloaded, some failed), watch mode logs a warning and continues to the next cycle instead of exiting. Transient failures are expected in long-running sessions - the next cycle retries failed assets automatically via the state database.

Only a complete failure (no files downloaded at all) causes the daemon to exit.

systemd Integration

On Linux, use --notify-systemd to integrate with systemd's service manager. kei sends:

  • READY=1 after authentication completes
  • STATUS= with cycle progress updates
  • STOPPING=1 on shutdown
  • WATCHDOG=1 heartbeats (if WatchdogSec= is configured)

Use --pid-file to write a PID file for service managers that need it.

Example systemd unit

[Unit]
Description=kei photo sync
After=network-online.target

[Service]
Type=notify
ExecStart=/usr/local/bin/kei sync \
    --username my@email.address \
    --download-dir /photos \
    --watch-with-interval 3600 \
    --notify-systemd \
    --pid-file /run/kei.pid
Restart=on-failure
WatchdogSec=7200

[Install]
WantedBy=multi-user.target

Related Flags

Clone this wiki locally