Upgrading the watcher
Keep instrument PCs on the latest watcher release with background auto-update, on-demand self-update, version pinning, and rollback.
This guide covers what happens between a new data-hub-watcher release published to
PyPI and the upgraded code running on a lab instrument PC. If you're installing the
watcher for the first time, start with Installing a watcher;
this assumes the watcher is already registered.
Cutting releases, flagging mandatory updates, and rolling the fleet back are admin workflows; see Managing watchers.
How upgrades reach a lab PC
Two paths deliver an upgraded wheel to the running watcher. Lab PCs running as a Windows service get the auto-update path for free; everything else upgrades on demand via the CLI.
Background auto-update
The in-process updater runs from the same heartbeat tick on every platform, not only Windows services. It polls the API once an hour and applies new releases on its own, with no operator action.
On each tick the watcher:
- Asks the server for the latest version and compares it against its own.
- Only attempts an upgrade if a newer version is available, no files have been uploaded for several heartbeats in a row, and no run has been reported recently. This activity-window guard exists so the watcher never takes itself down mid-acquisition. Releases an admin flags as mandatory skip this guard.
- Installs the new wheel and restarts into it (the Windows service restarts automatically via its failure-actions policy).
- Emits an
update_startedevent before the upgrade, thenupdate_succeededorupdate_failedafterwards, all visible on the dashboard.
Auto-update is disabled in the preview environment so pull-request preview deployments
can never push code to production lab PCs.
Manual upgrade (self-update)
Use this when you want an upgrade immediately, or on a non-service install.
data-hub-watcher self-update # check + upgrade if needed
data-hub-watcher self-update --check # report status only, no upgrade
data-hub-watcher self-update --force # re-run the upgrade subprocess
# even if the version already matchesThe command asks the API for the latest published version, compares it to the locally installed version, and runs the appropriate flow for your install method:
| Install method | Upgrade flow |
|---|---|
Windows + uv tool install | Routes through the DataHubWatcherUpgrade Scheduled Task, the same out-of-process worker the auto-updater uses. The CLI returns as soon as the task accepts; the service restart is automatic. Tail ~/.data-hub/upgrade-worker.log to watch progress. |
POSIX + uv tool install | uv tool install --reinstall data-hub-watcher==<latest> inline. Restart the watcher to pick up the new code. |
Plain venv pip install | <python> -m pip install -U data-hub-watcher==<latest> inline. Restart the watcher. |
Editable / uv sync checkout | Refused; upgrade manually with git pull && uv sync. |
The Windows uv-tool path requires that data-hub-watcher service install (or
service reinstall) has been run from an Administrator shell at least once: that's
what registers the upgrade Scheduled Task. See
Run as a Windows service.
After a successful upgrade on a POSIX or venv install you must restart the watcher
for the new code to take effect; self-update does not restart the running
process. To run upgrades unattended on a non-service install, schedule the CLI via
Windows Task Scheduler.
Pinning a specific version
To keep a PC on a particular release rather than tracking the server's latest version, pin it explicitly:
uv tool install data-hub-watcher==<pinned>Run data-hub-watcher self-update --check afterwards to confirm the server's
target. As long as the pin matches, the auto-update tick is a no-op; the moment the
server's target moves past your pin, the next tick will try to upgrade past it
again. To pin or roll back a whole fleet, an admin uses Settings → Watchers;
see Managing watchers.
Troubleshooting
update_started is followed by update_failed
The upgrade subprocess started but didn't end up running the new version. The
details.reason field tells you which sub-case fired:
subprocess raised: …: the command raised before exec. Check thatuvis on PATH for the service account.subprocess exited <N>: the upgrade command failed; details carry the last 1000 bytes of stdout/stderr (for example, a transient PyPI failure or a version not yet on the index).expected '<target>' after upgrade, running '<current>': install and restart succeeded but the old version still imports. Runuv tool uninstall data-hub-watcher && uv tool install data-hub-watcher==<target>as the service account.
update_failed without a preceding update_started
details.attempted_subprocess: false means the updater refused before running. The
most common reason is install method 'editable|unknown' not eligible for auto-update: the watcher detected a development install and refused to shadow your
source tree. Switch the host to a PyPI install, or ignore the event on a developer
machine.
Auto-update never fires
See Troubleshooting → Auto-update never fires.
self-update --check says “(none configured)”
The server has no latest version set for that environment. Benign: the CLI returns successfully and treats it as "no update available".
“Refusing to self-update an editable / unknown install”
You're running from a checkout. Upgrade manually with git pull && uv sync. To put
a developer machine onto a PyPI build, run uv tool install data-hub-watcher from a
separate shell for a parallel install on PATH.
Where to find the raw installer transcript
| Install path | Log file |
|---|---|
| In-process (POSIX, Windows pip) | ~/.data-hub/watcher.log (C:\ProgramData\DataHubWatcher\watcher.log on Windows) |
| Windows uv-tool worker | ~/.data-hub/upgrade-worker.log: every line of the installer's output with a UTC timestamp |
Both files are append-only and survive service restarts.
Run as a Windows service
Install and operate the Data Hub watcher as a Windows service so it starts automatically on boot, survives logouts, and auto-updates in the background.
Troubleshooting
Fix the watcher by symptom: won't start, files not detected, files not uploading, auto-update never fires, connection errors, and where to find the logs.