Active Feeds Daily Sync¶
Status: CURRENT / OPERATIONS
Purpose¶
This procedure defines the single versioned daily scheduler for every feed enabled by the canonical runtime activation authority.
The scheduler contains no merchant list, feed URL, credential, mapping, SQL or business rule. The active set is resolved inside the worker from CCX_ACTIVE_FEEDS through the existing feed registry and Sync Runner.
Architecture¶
systemd timer
↓
ccx-active-feeds-sync.service
↓
docker exec ccx-platform-worker
↓
wp ccx sync active-feeds
↓
application active-feeds action
↓
ccx_sync_runner_run_feeds()
↓
ccx_feeds_sources()
↓
CCX_ACTIVE_FEEDS authority
Each active feed is executed sequentially by the canonical Sync Runner. Existing per-feed locking, resumable-run semantics, batching and persistence remain owned by the runtime.
An exception raised while one feed runs is converted into a failed result for that feed. The runner continues with the remaining active feeds and returns an aggregate failure after all eligible feeds have been attempted.
Canonical command¶
docker exec -i ccx-platform-worker \
wp --allow-root --path=/var/www/html \
ccx sync active-feeds
The scheduled command takes no merchant argument. Adding or removing a merchant from daily scheduling is a CCX_ACTIVE_FEEDS configuration change, not a systemd change.
The targeted operator command remains available for diagnosis or controlled retry:
docker exec -i ccx-platform-worker \
wp --allow-root --path=/var/www/html \
ccx sync start --feed=<feed>
Schedule¶
OnCalendar=*-*-* 03:15:00 UTC
Persistent=true
RandomizedDelaySec=10m
TimeoutStartSec=23h
The former fixed Acer 04:15 UTC slot is retired. Active feeds now run sequentially from one scheduler authority; order comes from the canonical active feed registry.
The service safety ceiling is tied to the daily recurrence interval, not to a merchant count. TimeoutStartSec=23h leaves a margin before the next daily window while allowing CCX_ACTIVE_FEEDS to grow without editing systemd for every new merchant. Per-feed locks and resumable-run semantics remain authoritative inside the Sync Runner.
Source of truth¶
The only CURRENT scheduler units are:
operations/systemd/ccx-active-feeds-sync.service
operations/systemd/ccx-active-feeds-sync.timer
Merchant-specific scheduler units MUST NOT be tracked or installed as concurrent authorities. Installed copies under /etc/systemd/system/ must be byte-identical to the certified release files.
Migration¶
Run only from a certified release after explicit deployment approval:
SHA=<SHA_COMPLET_CERTIFIE>
RELEASE=/mnt/data/cmonchoix-release-authority/$SHA
systemd-analyze verify \
"$RELEASE/operations/systemd/ccx-active-feeds-sync.service" \
"$RELEASE/operations/systemd/ccx-active-feeds-sync.timer"
sudo install -m 0644 \
"$RELEASE/operations/systemd/ccx-active-feeds-sync.service" \
/etc/systemd/system/ccx-active-feeds-sync.service
sudo install -m 0644 \
"$RELEASE/operations/systemd/ccx-active-feeds-sync.timer" \
/etc/systemd/system/ccx-active-feeds-sync.timer
sudo systemctl disable --now ccx-samsung-sync.timer ccx-acer-sync.timer
if systemctl is-active --quiet ccx-samsung-sync.service || \
systemctl is-active --quiet ccx-acer-sync.service; then
echo 'ERROR: legacy merchant sync is still running; abort cutover and retry after it finishes.' >&2
exit 1
fi
sudo rm -f \
/etc/systemd/system/ccx-samsung-sync.service \
/etc/systemd/system/ccx-samsung-sync.timer \
/etc/systemd/system/ccx-acer-sync.service \
/etc/systemd/system/ccx-acer-sync.timer
sudo systemctl daemon-reload
sudo systemctl enable --now ccx-active-feeds-sync.timer
The legacy timers are disabled before the generic timer is enabled. The cutover fails closed if an already-started legacy service is still running, so both execution authorities cannot overlap. Both scheduling authorities must never be enabled at the same time.
Validation¶
systemctl is-enabled ccx-active-feeds-sync.timer
systemctl is-active ccx-active-feeds-sync.timer
systemctl list-timers ccx-active-feeds-sync.timer --all --no-pager
sha256sum \
"$RELEASE/operations/systemd/ccx-active-feeds-sync.service" \
/etc/systemd/system/ccx-active-feeds-sync.service \
"$RELEASE/operations/systemd/ccx-active-feeds-sync.timer" \
/etc/systemd/system/ccx-active-feeds-sync.timer
docker exec -i ccx-platform-worker \
wp --allow-root --path=/var/www/html \
help 'ccx sync active-feeds'
After a scheduled run, validate every active feed independently with ccx sync status --feed=<feed> --limit=1 and ccx sync doctor --feed=<feed>.
Failure handling¶
ccx sync active-feeds exits non-zero when one or more feeds fail. The unit deliberately has no Restart=on-failure: replaying the full active set after a partial failure would rerun feeds that already succeeded.
Use the journal to diagnose the aggregate failure, then retry only the failed feed when the cause is understood:
journalctl -u ccx-active-feeds-sync.service -n 200 --no-pager
docker exec -i ccx-platform-worker \
wp --allow-root --path=/var/www/html \
ccx sync start --feed=<failed-feed>
Do not create an ad-hoc cron or second timer.
Rollback¶
Rollback must restore one authority, never two. Use a previous certified release containing the retired units:
ROLLBACK_RELEASE=/mnt/data/cmonchoix-release-authority/<PREVIOUS_CERTIFIED_SHA>
sudo systemctl disable --now ccx-active-feeds-sync.timer
if systemctl is-active --quiet ccx-active-feeds-sync.service; then
echo 'ERROR: generic active-feeds sync is still running; abort rollback and retry after it finishes.' >&2
exit 1
fi
sudo install -m 0644 "$ROLLBACK_RELEASE/operations/systemd/ccx-samsung-sync.service" /etc/systemd/system/ccx-samsung-sync.service
sudo install -m 0644 "$ROLLBACK_RELEASE/operations/systemd/ccx-samsung-sync.timer" /etc/systemd/system/ccx-samsung-sync.timer
sudo install -m 0644 "$ROLLBACK_RELEASE/operations/systemd/ccx-acer-sync.service" /etc/systemd/system/ccx-acer-sync.service
sudo install -m 0644 "$ROLLBACK_RELEASE/operations/systemd/ccx-acer-sync.timer" /etc/systemd/system/ccx-acer-sync.timer
sudo rm -f /etc/systemd/system/ccx-active-feeds-sync.service /etc/systemd/system/ccx-active-feeds-sync.timer
sudo systemctl daemon-reload
sudo systemctl enable --now ccx-samsung-sync.timer ccx-acer-sync.timer
Never reconstruct legacy units manually on the VPS.
Security¶
Credentials and source URLs remain outside Git and systemd. Scheduler files contain only the stable worker command.