Skip to content

release: scheduler re-seed fix (#2975) + draft-integrity SQLite guard - #2978

Merged
jung-thomas merged 4 commits into
mainfrom
DEV
Nov 2, 2026
Merged

jung-thomas merged 4 commits into
mainfrom
DEV

Conversation

@jung-thomas

Copy link
Copy Markdown
Contributor

Emergency release — PROD scheduler outage

Promotes DEV→main to fix the ~day-long PROD scheduler outage.

Included (DEV ahead of main)

Test plan

  • Unit: run-with-lock (5) + scheduler-wedge/admin-job-controls/pipeline-log-reconciler (57) green on the fix branch
  • Post-PROD-deploy: metrics-rollup holds true 5-min cadence across ≥2 cycles with NO restart (DB-clock staleness: SECONDS_BETWEEN(lastSuccessAt, CURRENT_UTCTIMESTAMP))

…SQLite)

cds.fiori.draft_admin_integrity: true requires DB-level ON DELETE CASCADE
constraints on every draft table's DraftAdministrativeData_DraftUUID FK
(generated as .hdbconstraint, HANA-only — see srv/lib/draft-integrity-preflight.js,
which is explicitly isHanaKind-gated).

Unit tests run under the `development` profile on in-memory SQLite, where
those constraints do not exist. Without the cascade, activating a draft
leaves the active row with HasDraftEntity=true and DELETE(IsActiveEntity=true)
returns 403 DRAFT_ACTIVE_DELETE_FORBIDDEN_DRAFT_EXISTS. This is universal to
every draft-enabled entity (reproduced on Missions as well as GridTemplates),
not a per-test cleanup gap — the discard-then-delete band-aid in #2909 only
passed where the delete sat in a swallowed afterAll.

Scope the flag off under [development] only. hybrid (--profile hybrid) and
production run on HANA and keep the flag ON, so the optimized-deletion
behavior that #2909 depends on is unchanged in every environment that has
the constraints. Fixes the puzzle-grid-templates unit failure introduced by
the CAP 10.2 upgrade.
…s-draft-delete-flake

fix(cap): disable draft_admin_integrity under [development] profile (SQLite)
CAP 10.2.0 made the `.every().as()` singleton completion delete-then-reseed
guarded: the next occurrence is recreated only if CAP's own delete of the
status='processing' row removed it (_cnt > 0). runWithLock's #1021
belt-and-suspenders deleted that same row in its finally on every tick,
racing CAP's complete-tx; when our delete won, CAP saw _cnt=0, treated the
task as unscheduled concurrently, and skipped re-seeding — so every scheduled
job ran once then never rescheduled until a process restart. Harmless pre-10.2
(next occurrence was recreated unconditionally), fatal from 10.2 on.

Remove the per-tick deleteStuckOutboxRow call (and its now-unused import);
CAP 10.2 already guarantees exactly-once deletion in its complete-tx. Genuine
mid-flight tombstones remain covered by scheduler-reaper.js and the operator
forceUnwedge action (which still uses deleteStuckOutboxRow). Tests updated to
assert the row is NOT deleted per tick while JobLastRun still records.
…seed-2975

fix(scheduler): stop deleting singleton outbox row per tick (#2975)
@jung-thomas
jung-thomas merged commit 4177459 into main Nov 2, 2026
11 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.

1 participant