Skip to content

air: Use the run index for a self user filter and bound the index fallback in air list - #7619

Draft
artemy-kolesnikov wants to merge 2 commits into
mainfrom
CNXT-2479-air-list-fallback
Draft

artemy-kolesnikov wants to merge 2 commits into
mainfrom
CNXT-2479-air-list-fallback

Conversation

@artemy-kolesnikov

Copy link
Copy Markdown

Title: air: Use the run index for a self user filter and bound the index fallback in air list

Changes

  • --all-status --filter user=<own email> now uses the AiTrainingService index. air list resolved the current user only when no user= filter was set. So filtering on your own email never matched currentUser, and the command scanned the workspace's full Jobs run history. With --all-status, the current user is now resolved even when an explicit user= filter is given, and a case-insensitive match counts as self. If that lookup fails, the command keeps the old scan rather than failing. The default active view still makes no extra call.
  • The index fallback is visible and bounded. If the index load fails, the CLI now logs a Warn line instead of a Debug one (Warn is the CLI's default log level, so users see it on stderr). The line names the cause and says the CLI is falling back to a slower scan. That replacement scan can't use active_only, so it walks the full history. It is now capped at maxFallbackListScan = 250 runs instead of maxListScan = 2000. Hitting either cap warns "results may be incomplete. Narrow the search with --filter or a smaller --limit". The interactive table now gives the same warning when it exits; before, only one-shot output did.
  • Index requests fail fast. The index client is built from w.Config with HTTPTimeout = 15s and RetryTimeout = 15s, following the dedicated-client pattern in validateconfig.go. Before, they used the SDK defaults: a 60 s inactivity timeout and a 5 min retry window. The global SDK config is unchanged.
  • -o json stdout is unchanged. All new messages go to stderr.

Why

A report against a workspace with a large run history had air list take minutes to return a small number of rows. The traces showed each call walking every full-history runs/list page (several seconds per page), with no ai-training/workflows index request and no scim/Me call from the list path: the index was never attempted, because the user had passed --filter user=... or --all-users. A self filter is the case this PR fixes. Manually verified against a workspace: the same self-filtered --all-status list drops from minutes to a few seconds, with identical rows.

Tests

  • cmd/air/list_index_test.go:
    • TestListSelfUserFilterUsesIndex runs the full command (--all-status --filter user=me@…, JSON) against a stub server. It asserts one index call, zero runs/list calls, and the run in stdout. It fails on main: 0 index calls, 1 scan, empty result.
    • TestFallbackScanWarnsAndIsBounded: the index returns 500 and runs/list serves endless non-AIR pages. It asserts exactly 250/25 = 10 pages, no active_only, both warnings logged, and empty stdout.
    • TestRegularScanKeepsFullCap: --all-users still scans up to 2000 runs, with no fallback warning.
    • TestNewListStrategyGate: two new cases, self filter in a different case → index, and unknown current user → scan.
    • TestNewListStrategyFallsBackWhenIndexFails now uses a cmdio context. Its assertions are unchanged.
  • New acceptance fixture acceptance/air/list-index-fallback: the index returns 500. The text output shows the Warn line, and the JSON output (stderr dropped) is unchanged. No existing acceptance/air/list* golden changed: the new line appears only when the index fails, and no existing fixture fails it.
  • go test ./cmd/air/... passes. go test ./acceptance -run TestAccept/air/ passes (21 tests). gofmt and go vet are clean.

Follow-ups (not in this PR)

  • AICM / ai-training: --all-status walks the caller's whole index without a bound (63 pages for a heavy user, about 4 s). The index has no server-side ordering or limit. handleListTrainingWorkflows also ignores active_only, so the default active view can't use the index. Both need a server-side state filter plus an ordered, limited index.
  • --all-users --all-status is still a full-history scan, capped at 2000 runs. That is inherent to Jobs runs/list (several seconds per page on a busy workspace).
  • Python air CLI parity was skipped: the legacy CLI is frozen.

This pull request and its description were written by Isaac.

…lback in air list

`air list --all-status --filter user=<own email>` skipped the AiTrainingService
index because the current user was only resolved when no user filter was set, so
it scanned the workspace's full Jobs run history (minutes on a busy workspace).
Resolve the current user for --all-status and treat a case-insensitive match as
self, so that filter uses the index.

When the index load fails, warn instead of logging at debug, and cap the Jobs
scan that replaces it at 250 runs (it can't use active_only, so it walks the full
history). Give index requests a 15 s request timeout and retry window so a hung
index fails fast instead of waiting 60 s per page. Warn after the interactive
table exits when a scan hit its cap.

Co-authored-by: Isaac <no-reply@databricks.com>
@github-actions github-actions Bot added the AIR Databricks AI Runtime CLI label Nov 13, 2026
@github-actions

github-actions Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

Commit: ba33c5ce2 | Workflow run

Regression test report

Selected 1 changed tests (limit=20, 0 not selected)

1 tests: regression=1 unreleased=0 coverage=0 failing=0
test branch main (c4559ed) latest (v1.26.0)
TestAccept/air/list-index-fallback ✅ ❌ ❌
TestAccept/air/list-index-fallback: branch ✅ | main (c4559ed) ❌ | latest (v1.26.0) ❌

main (c4559ed):

acceptance_test.go:1374: Diff:
        --- air/list-index-fallback/output.txt
        +++ /tmp/TestAcceptairlist-index-fallback2319011935/002/output.txt
        @@ -2,7 +2,6 @@
         === list --all-status falls back to a bounded Jobs scan when the index fails (text)
         
         >>> [CLI] air list --all-status
        -Warn: air list: the AI Runtime run index is unavailable (failed to list training workflows: index unavailable); falling back to a slower scan of up to 250 recent job runs
            Run ID           Experiment  Status     Started              Duration  Progress  MLflow                  User                   Accelerators
            334747067049496  qwen-train  ● SUCCESS  [TIMESTAMP]       12s         -  qwen-train-001          [USERNAME]  8x H100
         
        
FAIL

latest (v1.26.0):

acceptance_test.go:1374: Diff:
        --- air/list-index-fallback/output.txt
        +++ /tmp/TestAcceptairlist-index-fallback361912709/002/output.txt
        @@ -2,7 +2,6 @@
         === list --all-status falls back to a bounded Jobs scan when the index fails (text)
         
         >>> [CLI] air list --all-status
        -Warn: air list: the AI Runtime run index is unavailable (failed to list training workflows: index unavailable); falling back to a slower scan of up to 250 recent job runs
            Run ID           Experiment  Status     Started              Duration  Progress  MLflow                  User                   Accelerators
            334747067049496  qwen-train  ● SUCCESS  [TIMESTAMP]       12s         -  qwen-train-001          [USERNAME]  8x H100
         
        @@ -18,12 +17,7 @@
                 "user": "[USERNAME]",
                 "status": "SUCCESS",
                 "started_at": "[TIMESTAMP]",
        -        "is_sweep": false,
        -        "experiment_name": "qwen-train",
        -        "duration_seconds": 12,
        -        "accelerator_type": "GPU_8xH100",
        -        "num_accelerators": 8,
        -        "dashboard_url": "[DATABRICKS_URL]/jobs/runs/334747067049496?o=[WORKSPACE_ID]"
        +        "is_sweep": false
               }
             ]
           }
        
FAIL

@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Collaborator

✅ Integration test report

Commit: ba33c5c

Run: 43529936109

Env 💚​RECOVERED ✅​pass 🙈​skip Time
💚​ aws linux-2core-8gb 1 270 16 6:15
💚​ aws-windows-latest-4core-16gb 1 272 14 5:19
💚​ azure linux-2core-8gb 1 269 16 5:21
💚​ azure-windows-latest-4core-16gb 1 271 14 3:31
💚​ gcp linux-2core-8gb 1 270 16 4:52
💚​ gcp-windows-latest-4core-16gb 1 272 14 3:53
Test Name aws linux-2core-8gb aws-windows-latest-4core-16gb azure linux-2core-8gb azure-windows-latest-4core-16gb gcp linux-2core-8gb gcp-windows-latest-4core-16gb
💚​ TestAccept 💚​R 💚​R 💚​R 💚​R 💚​R 💚​R
Top 3 slowest tests (at least 2 minutes):
duration env testname
3:27 azure-windows-latest-4core-16gb TestAccept
3:25 gcp-windows-latest-4core-16gb TestAccept
3:10 aws-windows-latest-4core-16gb TestAccept

…pdate the fallback golden

Co-authored-by: Isaac <no-reply@databricks.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AIR Databricks AI Runtime CLI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants