Skip to content

controllers/repos: ignore chacra callbacks older than the stored state - #160

Merged
djgalloway merged 1 commit into
mainfrom
wip-callback-ordering
Oct 30, 2026
Merged

djgalloway merged 1 commit into
mainfrom
wip-callback-ordering

Conversation

@djgalloway

@djgalloway djgalloway commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

chacra posts one callback per repo status change (requested, queued, building, ready, failed, deleted) from independent celery callback tasks (chacra/asynch/recurring.py, acks_late, retried after 30 s), with nothing ordering them. shaman applied whichever POST arrived last, so a late building could overwrite ready and the repo stayed building in shaman forever.

Evidence. That broke ceph-dev-pipeline build 10373 and a teuthology-suite run on 2026-10-28: shaman showed the rocky/10 default repo of ceph/wip-guits-main-2026-10-28-0918 as building while 3.chacra.ceph.com had it ready. shaman's nginx log has the ready POST at 13:23:04 and the building POST at 13:23:15. Cross-checking /api/search/?project=ceph&status=building against each record's chacra_url found 31 such stale records since 2026-10-15, across all three chacra nodes, and none before.

Fix. The payload already carries the repo's chacra-side modified, bumped by a before_update listener on every commit of the row. Within a build chacra commits between posting queued, building and ready, so the ready payload is always newer than the building payload of the same build, and a new build's requested carries at least the value its previous ready did. This stores the timestamp in a new repos.chacra_modified column (alembic revision a1f3c9d2e4b5) and ignores updates whose modified is older than the stored one, logging them at info. Equal values, payloads without modified, unparseable values and deleted are applied as before, so older chacra versions and existing API behaviour are unaffected.

chacra serializes the timestamp with str(datetime): naive when the row was loaded from its database, aware UTC when the listener just set it. Both forms are parsed and naive values are taken as UTC, which matches what the chacra nodes store (a ready repo's chacra modified is within 200 ms of shaman's own UTC modified for the same repo).

Deploying: the new column needs alembic upgrade head against the production database before the new code is started. Neither the ansible playbook (pecan populate) nor the openshift migration job runs upgrade, they only stamp head.

Tested: unit tests on sqlite and postgres 16 (181 passed), migration upgrade and downgrade on sqlite.

chacra posts each repo status change from an independent celery task,
so a late 'building' could overwrite a newer 'ready'. Store the repo's
chacra 'modified' timestamp (new repos.chacra_modified column, alembic
revision a1f3c9d2e4b5) and ignore updates whose 'modified' is older
than the stored one.

Assisted-by: Claude Fable 5.1
Signed-off-by: David Galloway <[email protected]>
@djgalloway
djgalloway force-pushed the wip-callback-ordering branch from 6f7c33f to cad2246 Compare October 28, 2026 19:47
@djgalloway
djgalloway requested review from dmick and zmc October 28, 2026 20:24
@djgalloway
djgalloway merged commit 331c67b into main Oct 30, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants