Skip to content

feat: add dynamic timeout retry with file-size-based parameters - #468

Open
aftersnow wants to merge 5 commits into
mainfrom
worktree-timeout-retry
Open

aftersnow wants to merge 5 commits into
mainfrom
worktree-timeout-retry

Conversation

@aftersnow

@aftersnow aftersnow commented Mar 23, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Add pkg/retrypolicy package with decoupled per-attempt timeout and retry budget:
    • Per-attempt timeout derives from file size (assumed 10 MiB/s minimum throughput, 2x safety factor, clamped to [5 min, 8 h]). Each attempt gets its own deadline.
    • Total attempt count and per-sleep cap are constants and do not scale with file size.
  • Replace cascading errgroup.WithContext cancellation with independent per-goroutine retry — one layer failure no longer cancels siblings.
  • Apply retry consistently across all data transfer paths: push, pull, fetch, build, and Dragonfly variants.
  • No new CLI flags. Retry behavior is determined entirely by package defaults; the public retrypolicy.Config struct stays available for programmatic embedders.

Motivation

When pushing large model files (multi-GB to multi-TB) to OCI registries backed by rate-limited storage (e.g., Harbor + OSS), i/o timeout errors frequently occur. The previous retry mechanism had three problems:

  1. Fixed retry parameters didn't account for file size — large files need longer per-attempt timeouts.
  2. Cascading cancellation via errgroup.WithContext meant one timeout killed all in-flight transfers.
  3. Coupled timing semantics — an earlier iteration introduced a single MaxRetryTime budget, but it covered both in-flight transfer time and inter-attempt sleeps. With a wall-clock that scales with file size, a slow first attempt could consume the whole budget, leaving no room for retries — exactly when retries matter most.

The current design splits the timing concerns into two independent constants, with no per-invocation overrides. We considered exposing them as CLI flags (--retry-attempts, --per-attempt-timeout) but found they were operational settings that rarely vary per invocation; YAGNI says skip until a real user case shows up.

Design

Concern Where it lives Scales with file size?
Per-attempt deadline ComputePerAttemptTimeout(fileSize) — file_size / 10 MiB/s × 2, clamped to [5 min, 8 h] Yes
Total attempts (initial + retries) DefaultMaxAttempts = 6 No
Per-sleep cap DefaultMaxBackoff = 2 min No
Initial backoff DefaultInitialDelay = 5 s No

Per-attempt deadlines are derived inside Do() via context.WithTimeout(ctx, perAttemptTimeout); the parent ctx is reserved for user cancellation. A DeadlineExceeded error under a live parent context is reclassified as retryable, so a single transfer timeout no longer short-circuits the retry loop.

Examples (ComputePerAttemptTimeout):

File size Per-attempt timeout
≤ 1 GB 5 min (floor)
10 GB ~34 min
70 GB ~4 h
≥ 140 GB 8 h (ceiling)

Changes

Area What changed
pkg/retrypolicy/ New package: Do(), IsRetryable(), ShortReason(), ComputePerAttemptTimeout()
pkg/backend/push.go Independent retry per layer, retrypolicy.Do for config/manifest
pkg/backend/pull.go Same pattern + pb.Placeholder() for retry progress display
pkg/backend/fetch.go Added retry (previously had none)
pkg/backend/build.go Config/manifest build wrapped in retry
pkg/backend/processor/base.go Removed cascading cancellation, added per-file retry
pkg/backend/pull_by_d7y.go, fetch_by_d7y.go Dragonfly paths use retry
internal/pb/pb.go Placeholder() method for retry backoff display
pkg/backend/retry.go Deleted (legacy defaultRetryOpts)

No new CLI flags or config fields.

Test plan

  • Unit tests in pkg/retrypolicy/retrypolicy_test.go, including a size-invariance test that pins the design's core property: total retry wall-clock does not depend on file size.
  • go vet ./... clean.
  • go test -race ./pkg/retrypolicy/... clean.
  • make lint clean (golangci-lint v2.5.0).
  • E2E workflow passed on GitHub Actions.
  • Manual large-file push test against rate-limited registry.

@gemini-code-assist

Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the robustness of file transfer operations by introducing a dynamic and intelligent retry mechanism. It addresses previous limitations where fixed retry parameters and cascading cancellations led to frequent failures, especially with large files over unreliable networks. The new system adapts retry behavior based on file size and isolates failures, ensuring that individual transient errors do not disrupt the entire transfer process, thereby improving overall reliability and user experience.

Highlights

  • Dynamic Retry Policy: Implemented a new pkg/retrypolicy package that provides dynamic retry parameters (max retry time and max backoff) based on file size. Small files (<=1GB) use 10min/1min backoff, large files (>=10GB) use 60min/10min backoff, with linear interpolation for sizes in between.
  • Independent Per-Goroutine Retry: Replaced the cascading cancellation mechanism of errgroup.WithContext with independent retry logic for each concurrent operation (e.g., layer transfer). This ensures that a transient failure in one operation does not cancel all other in-flight transfers.
  • New CLI Flags: Added --no-retry to disable retries and --retry-max-time to set a custom maximum total retry duration per file (0 for dynamic) to the push, pull, build, and fetch commands.
  • Consistent Retry Application: Applied the new dynamic retry logic consistently across all data transfer paths, including push, pull, fetch, build, and their respective Dragonfly variants.
  • Progress Bar Integration: Introduced a Placeholder() method in the progress bar utility to display retry backoff messages, providing better user feedback during transient network issues.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a robust dynamic retry mechanism with file-size-based parameters, which is a significant improvement for handling transient network errors during large file transfers. The new pkg/retrypolicy is well-designed and thoroughly tested. A key architectural improvement is replacing cascading errgroup.WithContext with independent per-goroutine retries, preventing a single failure from terminating all concurrent operations. The addition of CLI flags for retry control and progress bar updates on retry significantly enhance usability. The changes are consistently applied across all data transfer paths. I have a couple of suggestions for improvement in pkg/backend/push.go to ensure a consistent user experience during retries.

Comment thread pkg/backend/push.go
Comment thread pkg/backend/push.go
@aftersnow
aftersnow force-pushed the worktree-timeout-retry branch from 9f96098 to 1369e47 Compare March 23, 2026 12:55
@aftersnow

Copy link
Copy Markdown
Contributor Author

/gemini review

@aftersnow

Copy link
Copy Markdown
Contributor Author

@codex-code-assist review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a significant improvement to the application's resilience by implementing a dynamic, file-size-based retry mechanism for data transfers. The new pkg/retrypolicy is well-designed and replaces the previous fixed retry logic. A key architectural change is the move away from cascading cancellations in errgroup, which will prevent a single failure from halting all concurrent operations. The addition of CLI flags for retry control is also a valuable feature. My review focuses on a critical race condition in the progress bar handling, a minor bug in the retry backoff calculation for logging, and opportunities to reduce code duplication for better maintainability.

Comment thread internal/pb/pb.go Outdated
Comment thread pkg/backend/fetch.go Outdated
Comment thread pkg/backend/fetch_by_d7y.go Outdated
Comment thread pkg/backend/pull_by_d7y.go Outdated
Comment thread pkg/retrypolicy/retrypolicy.go Outdated
Comment thread pkg/retrypolicy/retrypolicy.go

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: eb1fc1ebc2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkg/retrypolicy/retrypolicy.go Outdated
Comment on lines +222 to +223
// Unknown errors default to retryable.
return true

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Stop retrying unclassified errors as transient

This fallback makes every unexpected error retryable, and the new call sites now feed retrypolicy.Do with arbitrary local failures from paths like builder.BuildLayer and extractLayer. A permanent problem such as permission denied or no space left on device will now sit in the retry loop until the size-based deadline expires (10 minutes for small files, 60 minutes for blobs ≥10 GiB), so broken builds/pulls can appear hung for a long time instead of failing promptly.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point — the permanent-vs-transient split needs a deliberate allowlist (network timeouts, 5xx, connection resets, rate-limit responses, ...) rather than ad-hoc narrowing. Leaving for follow-up; I'll send a dedicated PR once we agree on the list so this one can land without scope creep.

Comment thread pkg/backend/pull.go Outdated
@aftersnow

Copy link
Copy Markdown
Contributor Author

/gemini review

@aftersnow

Copy link
Copy Markdown
Contributor Author

@codex-code-assist review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a robust and dynamic retry mechanism based on file size, significantly improving the reliability of data transfer operations. The refactoring to use a dedicated pkg/retrypolicy package centralizes retry logic, and the move to independent per-goroutine retries effectively addresses the cascading cancellation issue. The addition of CLI flags for retry configuration provides users with greater control. The comprehensive unit tests for the new retry policy are commendable, ensuring the correctness of the dynamic parameter calculations and error handling.

Overall, this is a well-designed and implemented feature that directly tackles a critical pain point for large file transfers.

Comment thread pkg/backend/push.go Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f3fbdfe46a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkg/backend/push.go Outdated
Comment thread pkg/backend/pull.go Outdated
Comment thread pkg/backend/processor/base.go Outdated
@aftersnow

Copy link
Copy Markdown
Contributor Author

@codex-code-assist review

@aftersnow
aftersnow force-pushed the worktree-timeout-retry branch 2 times, most recently from 1f6c0f5 to fcdbcb0 Compare March 24, 2026 06:34
aftersnow added a commit that referenced this pull request Apr 23, 2026
retry-go's OnRetry callback supplies a 1-based retry attempt number,
so computeBackoff(n+1, ...) logged a delay that was one doubling
ahead of the actual backoff used by the retry loop. Pass n directly.

Also drop the unreachable attempt == 0 branch in computeBackoff
(retry-go never supplies 0) and skip that case in the test.

Addresses review feedback on PR #468 (gemini).

Signed-off-by: Zhao Chen <winters.zc@antgroup.com>
aftersnow added a commit that referenced this pull request Apr 23, 2026
The 'prefer modelspec.AnnotationFilepath, fall back to the legacy
dragonflyoss key' pattern was duplicated across fetch.go,
fetch_by_d7y.go, and pull_by_d7y.go (six call sites total). Centralize
it in backend.getAnnotationFilepath so each caller is a one-liner and
future changes to the annotation resolution live in one place.

Addresses review feedback on PR #468 (gemini).

Signed-off-by: Zhao Chen <winters.zc@antgroup.com>
aftersnow added a commit that referenced this pull request Apr 23, 2026
Three call sites (push, pull, processor) used 'g.Wait()' without
capturing its return, so a cancelled worker's ctx.Err() could be
discarded. In the edge case where all running uploads/layers succeed
but queued-but-unstarted workers exit via the ctx.Done() select,
errs stayed empty and the operation continued to config/manifest push
(or finalized a partial descriptor set), potentially publishing an
incomplete artifact. Capture the Wait() result into errs and rely on
the existing ctx.Err()/len(errs) checks to return cleanly. Also change
processor/base.go's select from 'return nil' to 'return ctx.Err()' so
the same propagation path applies there.

Additionally, align push.go's OnRetry with pull.go/fetch.go by using
pb.Placeholder (designed to reset an existing bar's message and
progress) instead of pb.Add for layer, config, and manifest retries.

Addresses review feedback on PR #468 (codex P1, gemini).

Signed-off-by: Zhao Chen <winters.zc@antgroup.com>
@aftersnow
aftersnow marked this pull request as draft April 23, 2026 05:58
@aftersnow

Copy link
Copy Markdown
Contributor Author

@codex-code-assist review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fc3ac13156

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pkg/retrypolicy/retrypolicy.go Outdated
@aftersnow

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a specialized retrypolicy package to manage blob transfer retries, decoupling per-attempt timeouts from the retry backoff strategy. It adds CLI flags for retry configuration across the build, fetch, pull, and push commands and refactors the backend to use this new policy, improving error handling and progress tracking. A Placeholder method was added to the progress bar to handle resets during retries. Feedback suggests centralizing the progress bar reset logic within the Placeholder method and adopting the go-humanize library for byte formatting to eliminate redundant code.

Comment thread internal/pb/pb.go Outdated
Comment thread pkg/backend/fetch.go Outdated
Comment thread pkg/backend/fetch_by_d7y.go Outdated
Comment thread pkg/backend/pull_by_d7y.go Outdated
Comment thread pkg/retrypolicy/retrypolicy.go
Comment thread pkg/retrypolicy/retrypolicy.go

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a new pkg/retrypolicy package to provide consistent retry behavior across all blob-transfer and build paths, including dynamic per-attempt timeouts derived from file size, while also removing cascading cancellation caused by errgroup.WithContext so one failing transfer no longer cancels siblings.

Changes:

  • Added pkg/retrypolicy with Do(), IsRetryable(), ShortReason(), and ComputePerAttemptTimeout() plus unit tests.
  • Reworked push/pull/fetch/build/processor (including Dragonfly variants) to use retrypolicy.Do and to aggregate errors instead of canceling sibling goroutines.
  • Added ProgressBar.Placeholder() to keep progress entries visible during retry backoff.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/retrypolicy/retrypolicy.go New retry policy implementation with per-attempt timeouts and retry classification.
pkg/retrypolicy/retrypolicy_test.go Unit tests for timeout sizing, retryability, backoff, and Do() behavior.
pkg/config/push.go Import formatting cleanup.
pkg/config/build.go Import formatting cleanup.
pkg/backend/retry_test.go Removed legacy retry tests tied to the old retry helper.
pkg/backend/push.go Uses retrypolicy.Do and aggregates per-layer errors without cascading cancellation.
pkg/backend/pull.go Uses retrypolicy.Do per layer/config/manifest and aggregates errors without canceling siblings.
pkg/backend/pull_by_d7y.go Applies retrypolicy.Do to Dragonfly pull/extract path and aggregates errors.
pkg/backend/processor/options.go Removes legacy defaultRetryOpts (retry is now centralized).
pkg/backend/processor/base.go Uses retrypolicy.Do per-file build layer processing; aggregates errors instead of canceling.
pkg/backend/fetch.go Adds retry to fetch path and aggregates errors across concurrent fetches.
pkg/backend/fetch_by_d7y.go Applies retry to Dragonfly fetch/extract path and aggregates errors.
pkg/backend/build.go Wraps config/manifest build steps in retrypolicy.Do.
pkg/backend/annotation.go Adds getAnnotationFilepath() helper with legacy-key fallback.
internal/pb/pb.go Adds ProgressBar.Placeholder() for retry/backoff UI display.
cmd/push.go Flag formatting changes (multi-line flags.*Var calls).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/retrypolicy/retrypolicy.go Outdated
Comment thread pkg/retrypolicy/retrypolicy.go Outdated
@aftersnow
aftersnow marked this pull request as ready for review July 7, 2026 04:02
@aftersnow
aftersnow force-pushed the worktree-timeout-retry branch from 0caa268 to aba6978 Compare July 7, 2026 04:22

@aftersnow aftersnow left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Reviewed with focus on the new retry loop, concurrency behavior, and progress-bar changes. Build, go vet, and go test -race all pass locally. The core design (per-attempt timeout decoupled from a fixed retry budget) is sound and well-tested — the size-invariance test pins the key property nicely, and the msg data-race fix in internal/pb is correct.

Main findings (details inline):

  1. Jitter is dead code — DelayType(BackOffDelay) drops retry-go's default RandomDelay combination, so MaxJitter never applies. Concurrent layers that fail together retry in lockstep against a rate-limited registry — the exact scenario this PR targets. Empirically confirmed.
  2. OnRetry fires after the final failed attempt — logs/progress promise a retry that never happens.
  3. Retry progress UX is inconsistent across push/pull/fetch paths, and Placeholder on an aborted bar may render nothing.
  4. BeforePullLayer hook runs once-outside-retry in fetch.go but per-attempt in the other three paths.
  5. Minor: Config doc drift ("CLI flags"), hand-rolled humanizeBytes (1024 divisor with SI labels), 2024 copyright on new files, misleading // never return error to errgroup comment.

One doc suggestion: state explicitly that the worst case per blob is ~6 × 8h ≈ 48h with no overall budget — the parent context is the only bound.

Comment thread pkg/retrypolicy/retrypolicy.go Outdated
Comment thread pkg/retrypolicy/retrypolicy.go
Comment thread pkg/retrypolicy/retrypolicy.go Outdated
Comment thread pkg/retrypolicy/retrypolicy.go
Comment thread pkg/retrypolicy/retrypolicy.go Outdated
Comment thread pkg/backend/push.go Outdated
Comment thread pkg/backend/pull.go Outdated
Comment thread pkg/backend/fetch.go
Add pkg/retrypolicy with decoupled per-attempt timeout and retry budget:
- Per-attempt timeout derives from file size (10 MiB/s floor, 2x safety),
  clamped to [5min, 8h]; each attempt gets its own deadline.
- Total attempts and per-sleep backoff cap are constants, independent of
  file size.
- Replace cascading errgroup.WithContext cancellation with independent
  per-goroutine retry so one layer failure no longer cancels siblings;
  errors are collected and joined.
- Apply retry across push, pull, fetch, build, and the Dragonfly variants.
- IsRetryable uses an allowlist; unclassified errors are permanent.
- Guard the progress bar message with a lock (data-race fix) and add
  Placeholder() for retry-backoff display.

Squashed and rebased onto main; integrated with the iometrics Tracker
and the updated BeforePullLayer/AfterPullLayer hook signatures.

Claude-Session: https://claude.ai/code/session_01HHaMSeWpe3apQEx7n4UvRg
Signed-off-by: Zhao Chen <winters.zc@antgroup.com>
Functional bugs:
- retrypolicy: re-enable jitter by combining BackOffDelay with RandomDelay
  when jitter > 0 (guarding rand.Int63n(0) panic when it is 0). Passing
  BackOffDelay alone had made MaxJitter dead code, causing concurrent layers
  to retry in lockstep against a rate-limited registry.
- retrypolicy: stop forwarding OnRetry after the final failed attempt so
  logs and progress bars no longer promise a retry that never happens.

Consistency:
- Add backend.newRetryPlaceholder and route push/pull/fetch and both
  Dragonfly paths through it for a uniform retry progress message.
- pb.Placeholder: recreate an aborted/completed bar so the retry message
  actually renders, and fold in the SetRefill/EwmaSetCurrent reset.
- Run BeforePullLayer/AfterPullLayer once outside the retry loop in pull,
  pull_by_d7y and fetch_by_d7y, matching fetch's contract.

Cleanup:
- humanizeBytes: delegate to go-humanize IBytes (correct KiB/MiB/GiB).
- Reword Config/minThroughput docs (programmatic embedders; no CLI flags).
- Bump new-file copyright to 2025; fix push.go errgroup comment.

Add regression tests for the OnRetry-after-final-attempt and jitter paths.

Signed-off-by: Zhao Chen <winters.zc@antgroup.com>
Signed-off-by: Zhao Chen <winters.zc@antgroup.com>
@aftersnow
aftersnow force-pushed the worktree-timeout-retry branch from e6bbd34 to 601092c Compare September 7, 2026 14:49
@bergwolf
bergwolf enabled auto-merge (squash) October 10, 2026 14:26
@bergwolf

Copy link
Copy Markdown
Member

Please add your SOB line in commit 601092c to pass DCO check. Otherwise lgtm.

Signed-off-by: Zhao Chen <zhaochen.zju@gmail.com>
@aftersnow
aftersnow force-pushed the worktree-timeout-retry branch from 601092c to c54a890 Compare October 10, 2026 14:50
Conflicts resolved:

- internal/pb/pb.go: keep main's atomic.Value message (#474) and drop the
  msgMu lock; Placeholder stores the message through the atomic value.
- internal/pb/pb_test.go: keep main's test file and add the Placeholder
  tests, including the message concurrency test, on top of it.
- pkg/backend/processor/base.go: keep the per-attempt retry context and
  add main's OnHash hook.
- pkg/backend/push.go: keep the per-attempt retry context and main's
  pushIfNotExist signature without the prompt argument. Retry prompts
  use main's phase names (Pushing blob / Pushing config).

Signed-off-by: Zhao Chen <zhaochen.zju@gmail.com>
@aftersnow

Copy link
Copy Markdown
Contributor Author

@bergwolf @chlins Update:

PTAL.

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

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants