Aller au contenu

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.