Skip to content

Retry workspace get-status on transient failures during sync - #7044

Merged
janniklasrose merged 4 commits into
mainfrom
janniklasrose/retry-workspace-get-status
Oct 14, 2026
Merged

janniklasrose merged 4 commits into
mainfrom
janniklasrose/retry-workspace-get-status

Conversation

@janniklasrose

@janniklasrose janniklasrose commented Oct 14, 2026 •

Copy link
Copy Markdown
Member

Changes

EnsureRemotePathIsUsable validates the sync target with a workspace/get-status read. Its calls now go through libs/retry (added in #7014) with a new retry.IsTransientRead predicate: on top of the 5xx/408 errors IsTransient already covers, an idempotent read is also safe to replay after a transport-level failure that produced no HTTP response (a *url.Error, e.g. the HTTP/2 REFUSED_STREAM in #6472). IsTransient (used for the write path) is left unchanged.

Why

#6472: a sporadic HTTP/2 REFUSED_STREAM on the get-status call during bundle deploy aborted the deploy and left the bundle out of sync with its artifacts. #7014 added upload retries; this extends the same approach to the get-status read that was the actual point of failure.

Tests

  • Unit test for IsTransientRead (5xx/408, a REFUSED_STREAM *url.Error, and the non-retriable cases).
  • Acceptance test (cmd/sync/get-status-504) injecting a 504 on GET /api/2.0/workspace/get-status during databricks sync; the read is retried and the sync succeeds. The transport-error branch is unit-tested rather than acceptance-tested: the HTTP testserver can't produce a real stream error, and Go's transport auto-retries idempotent GETs on reused connections, which makes a forced-disconnect fault non-deterministic to assert.

Builds on #7014 (now merged).

This pull request and its description were written by Isaac.

Base automatically changed from denik/file-upload-retries to main October 14, 2026 10:06
@eng-dev-ecosystem-bot

eng-dev-ecosystem-bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Integration test report

Commit: 6684fff

Run: 38566908155

Env ✅​pass 🙈​skip Time
✅​ aws linux-2core-8gb 276 17 5:36
✅​ aws-windows-latest-4core-16gb 278 15 4:48
✅​ azure linux-2core-8gb 275 17 6:11
✅​ azure-windows-latest-4core-16gb 277 15 4:20
✅​ gcp linux-2core-8gb 276 17 5:28
✅​ gcp-windows-latest-4core-16gb 278 15 4:21
Top 3 slowest tests (at least 2 minutes):
duration env testname
4:06 azure-windows-latest-4core-16gb TestAccept
3:06 gcp-windows-latest-4core-16gb TestAccept
3:03 aws-windows-latest-4core-16gb TestAccept

janniklasrose and others added 2 commits October 14, 2026 10:57
EnsureRemotePathIsUsable validates the sync target with workspace/get-status. A transient server error or a dropped connection (e.g. REFUSED_STREAM, #6472) on that read aborted the whole deploy. Route the calls through libs/retry with a new IsTransientRead predicate: on top of the 5xx/408 that IsTransient covers, an idempotent read is also safe to replay after a transport-level failure (*url.Error).

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
@janniklasrose
janniklasrose force-pushed the janniklasrose/retry-workspace-get-status branch from cb37d03 to d339309 Compare October 14, 2026 10:59
@janniklasrose
janniklasrose marked this pull request as ready for review October 14, 2026 11:05
@janniklasrose
janniklasrose requested review from a team as code owners October 14, 2026 11:05
Comment thread libs/retry/retry.go
@@ -0,0 +1,4 @@
Warn: retrying after 504 Gateway Timeout from GET /api/2.0/workspace/get-status

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to log it at Warn level? Maybe just a debug one?

@janniklasrose janniklasrose Oct 14, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

following #7014 here but we can do that as follow-up for both. agree that customers don't need to see these internal details

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that it's rare I personally would not mind seeing some progress instead of just CLI appears being blocked.

janniklasrose and others added 2 commits October 14, 2026 11:19
Matching every *url.Error restarted the SDK's RetryTimeout loop (5m default) for the transport errors it already retries (connection reset/refused, i/o timeout, TLS), turning a persistent failure's ~5m into ~15m. Retry only the HTTP/2 REFUSED_STREAM the SDK leaves unhandled (#6472).

Co-authored-by: Isaac <no-reply@databricks.com>
Co-authored-by: Isaac <no-reply@databricks.com>
@janniklasrose
janniklasrose added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit a689393 Oct 14, 2026
26 checks passed
@janniklasrose
janniklasrose deleted the janniklasrose/retry-workspace-get-status branch October 14, 2026 13:23
deco-sdk-tagging Bot added a commit that referenced this pull request Oct 14, 2026
## Release v1.21.0

### CLI

 * Support pipeline IDs in `pipelines history`. ([#6995](#6995))
 * Show a hint for previewing more rows in `pipelines show`. ([#6995](#6995))
 * `databricks environments setup-local` now uses the environment in `UV_PROJECT_ENVIRONMENT` when it is set, as `uv sync` does. ([#7026](#7026))
 * `databricks environments setup-local` now supports uv workspace members: it uses the shared `.venv` at the workspace root and writes the dependency constraints to the root `pyproject.toml`. ([#7018](#7018))

### AI Runtime

 * Limit `databricks air run` submission preflight validation to one five-second attempt before continuing when the service is unavailable. ([#6994](#6994))

### Bundles

 * Bundle file uploads now use the multipart `POST /api/2.0/workspace/import` endpoint instead of the deprecated `POST /api/2.0/workspace-files/import-file`, raising the per-workspace upload rate limit and improving deploy throughput under concurrency. ([#6149](#6149))
 * Diagnostic paths now quote map keys that are not identifiers, e.g. `resources.jobs['${var.env}_job']`. ([#6980](#6980))
 * No longer include `CLAUDE.md` in the bundle templates, now that Claude supports `AGENTS.md`. ([#7000](#7000))
 * Fix `bundle deployment bind` silently binding over a deployment state it could not read, which could take over a resource that was already managed by the bundle. ([#6331](#6331))
 * `databricks bundle deploy`, `databricks bundle sync` and `databricks sync` now retry file, library, state and metadata uploads that fail with a transient server error (5xx or 408), instead of failing. ([#7014](#7014))
 * `databricks bundle deploy`, `databricks bundle sync` and `databricks sync` now retry the workspace path check (`workspace/get-status`) when it fails with a transient server error (5xx or 408) or an HTTP/2 `REFUSED_STREAM`, instead of failing. ([#7044](#7044))
 * Fixed `experimental.immutable_folder` failing validation for targets with `mode: development` ("file_path must start with '~/' or contain the current username"). ([#7027](#7027))
 * Fixed `experimental.immutable_folder` failing with `experimental.deployment_history` ("workspace_info.file_path must be an absolute workspace path") and failing `bundle validate` when top-level `permissions` are set. ([#7001](#7001))
 * Translate relative `.env` file paths in a job's `environment_variables[].spec.files` to their deployed workspace locations. ([#6985](#6985))
 * Resolve job `project_environment` paths relative to the YAML file that defines them. ([#6983](#6983))

### Dependency Updates

 * Bump Go toolchain to 1.26.9. ([#6996](#6996))
 * Update Go SDK to 0.188.0. ([#7038](#7038))
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.

4 participants