Skip to content

Fix Data Management step badges stuck on running for finished steps - #1296

Merged
Paul Lizer (paullizer) merged 2 commits into
microsoft:Developmentfrom
paullizer:fix/1272-step-status-lifecycle
Aug 19, 2026
Merged

Fix Data Management step badges stuck on running for finished steps#1296
Paul Lizer (paullizer) merged 2 commits into
microsoft:Developmentfrom
paullizer:fix/1272-step-status-lifecycle

Conversation

@paullizer

Copy link
Copy Markdown
Contributor

Fixes #1272

Related: #1258, #1271, #1276 (all merged/closed).

Problem

On a finished Data Management job the details panel misrepresented state twice:

  1. Timeline entries for steps that had clearly finished — Cosmos DB export step completed, AI Search export step completed, Source blob export step completed — still showed a running badge.
  2. Live metrics still showed Current container: Waiting on a job already at completed_with_warnings.

Together these made a completed job look stuck. The history read as "queued → running → complete" at the job level while individual steps never advanced past running.

Root Cause

_set_job_progress() used a single status value for two different things — the job document and the timeline event it recorded:

job.update({"status": status, ...})
_record_data_management_job_event(..., status=status, ...)   # job status, not step outcome

Every call site announcing a finished step relied on the default DATA_MANAGEMENT_STATUS_RUNNING:

_set_job_progress(job, "Cosmos DB export step completed", 1, total_steps, current_step="cosmos")

The event was historically accurate — the job was running when the step finished — but the timeline presents that badge as the step's state. There was no way to express "this step is done, the job is not" because both shared one field.

Four migration events recorded directly through _record_data_management_job_event had the same defect: migration-plan, migration-preflight, migration-cosmos-{target_type}, migration-reconciliation all describe finished work but were stamped running.

The queued half of the report was not a defect. Every event call site passes an explicit status, so the queued default on _record_data_management_job_event is never stranded on a step — the queued and *-retry-queued entries genuinely describe queueing actions.

Changes

  • functions_data_management.py
    • Added a step_status parameter to _set_job_progress that governs only the recorded timeline event, plus a _complete_job_step helper.
    • Moved the 15 step-completion call sites onto it across backup, restore, and migration.
    • Corrected the 4 migration outcome events stamped running.
    • step_status defaults to None and falls back to status, so untouched call sites keep their behavior: steps that start still report running, and genuinely terminal calls such as Restore completed still propagate their terminal status to both the job and the event.
  • admin_data_management.js — added isTerminalJobStatus and gated live-only telemetry. Finished jobs stop rendering Current container: Waiting and migration Liveness: Running. Cumulative metrics (processed, transferred, request units, retries, skipped/failed) still render.

Resulting per-step lifecycle: running when a step begins, completed when it finishes, while the job stays running until it actually completes.

Validation

  • functional_tests/test_data_management_job_step_status.py18 passed (new file)
  • Data Management suite (-k data_management) — 175 passed, only the two known pre-existing issues (swagger_wrapper collection error in test_admin_endpoint.py, and test_backup_recovery_and_admin_progress_are_bounded_and_sanitized)

Regression probe: reverting status=step_status or status back to status=status fails test_finished_step_is_completed_while_job_keeps_running with AssertionError: assert 'running' == 'completed', confirming the test fails for the right reason.

Impact

Timeline entry Before After
Cosmos DB export step completed running completed
AI Search export step completed running completed
Source blob export step completed running completed
Migration reconciliation completed running completed
Started step (e.g. Migrating Cosmos records) running running
Job status while steps complete running running
Panel row on a finished job Before After
Current container Waiting hidden
Liveness (migration) Running - ... hidden

Note on versioning

This branch bumps to 0.260.003. PR #1295 (Backup Inventory) bumps to 0.260.002 from the same base, so config.py and the top of release_notes.md will conflict trivially if both merge — resolve by keeping both sections.

Fixes microsoft#1272

Completed job steps showed a "running" badge on the Data Management job
timeline, and finished backup jobs still displayed "Current container:
Waiting". Together these made a completed job look stuck.

_set_job_progress used one status value for two different things: the job
document and the timeline event it recorded. Every call site announcing a
finished step relied on the default DATA_MANAGEMENT_STATUS_RUNNING, so
"Cosmos DB export step completed" was recorded as running. The event was
historically accurate, but the timeline presents that badge as the step's
own state, and there was no way to express "this step is done, the job is
not" because both shared one field.

Add a step_status parameter that governs only the recorded event, plus a
_complete_job_step helper, and move the 15 step-completion call sites onto
it across backup, restore, and migration. step_status defaults to None and
falls back to status, so untouched call sites keep their behavior: steps
that start still report running, and genuinely terminal calls such as
"Restore completed" still propagate their terminal status to both the job
and the event.

Also correct four migration outcome events recorded directly through
_record_data_management_job_event (migration-plan, migration-preflight,
migration-cosmos-{target_type}, migration-reconciliation) which describe
finished work but were stamped running.

The "queued" half of the report was not a defect. Every event call site
passes an explicit status, so the queued default is never stranded on a
step; the queued and *-retry-queued entries genuinely describe queueing.

On the frontend, add isTerminalJobStatus and gate live-only telemetry so
finished jobs stop rendering "Current container: Waiting" and migration
"Liveness: Running". Cumulative metrics still render on finished jobs.

Validation: 18 passed in the new step status suite; 175 passed across Data
Management with only the two known pre-existing issues. Regression probe
reverting step_status fails with "assert 'running' == 'completed'".
Resolves conflicts introduced by PR microsoft#1295 (Backup Inventory GROUP BY fix)
landing on Development first.

- config.py: keep 0.260.003, which supersedes the 0.260.002 from microsoft#1295.
- release_notes.md: keep both sections, newest first (0.260.003 above
  0.260.002). Neither entry replaces the other.

functions_data_management.py auto-merged cleanly; the two changes touch
different regions (_count_data_management_backups vs _set_job_progress /
_complete_job_step) and both are present after the merge.

Validation: 177 passed across the Data Management suite, with only the two
known pre-existing issues (swagger_wrapper collection error in
test_admin_endpoint.py, and
test_backup_recovery_and_admin_progress_are_bounded_and_sanitized).
@paullizer
Paul Lizer (paullizer) merged commit fa5b1c2 into microsoft:Development Aug 19, 2026
10 of 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