Retry transient statuses

Ouverte
#2,964 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

Personne n'a encore pris cette issue.

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
48/100
Type d'issue
Bug
Clarté
Plutôt claire
Activité
Active
Stack technique
go
Domaine
build-system

Piste de recherche

Start with internal/devpkg/narinfo_cache.go, especially fetchNarInfoStatusFromHTTP, areExpectedOutputsInCacheOnce, and FillNarInfoCache; then trace how internal/devpkg/package.go handles a cache miss. The issue suggests several possible remedies, so clarify the chosen scope before changing behavior. Done means transient HTTP failures are not silently treated as genuine cache misses, with the selected behavior covered by relevant tests.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

feature looks easy p3 processed triage
What problem are you trying to solve?

A single transient non-200 from cache.nixos.org makes devbox run fail hard, even
when every store path is already present in the local nix store.

On a GitHub Actions runner, with the whole /nix/store restored from cache moments
earlier:

Info: Ensuring packages are installed.
Error: error running script "echo" in Devbox: execute template flake.nix.tmpl:
template: flake.nix.tmpl:52:33: executing "flake.nix.tmpl" at
<$pkg.InputAddressedPathForOutput>: error calling InputAddressedPathForOutput:
Package "gdk-pixbuf@latest" cannot be fetched from binary cache store

All six gdk-pixbuf x86_64-linux store paths in our devbox.lock return 200 from
cache.nixos.org, before and after the failure. Re-running the identical job, same
commit, same lockfile, succeeded with no changes. Out of 45 jobs in that CI run using
the same lockfile at the same moment, exactly one failed.

Root cause

fetchNarInfoStatusFromHTTP treats any non-200 as "this path is not in the cache"
(internal/devpkg/narinfo_cache.go:228):

return res.StatusCode == http.StatusOK, nil

A 429, 503 or 403 from the CDN is therefore recorded identically to a genuine
404. There is no retry, and the request carries a 5s deadline
(narinfo_cache.go:216).

That result then propagates as fact:

  • areExpectedOutputsInCacheOnce (narinfo_cache.go:89) requires every default
    output to be present: len(outputToCache) == len(outputs).
  • Packages with two default outputs need 2/2 hits. In our lock that's gdk-pixbuf
    (out + man), plus ffmpeg, gnumake, just, libheif, perl,
    pkg-config and qpdf so they lose twice as often.
  • IsInBinaryCache returns false, and InputAddressedPathForOutput
    (internal/devpkg/package.go:604) aborts template rendering.

Concurrency makes a transient response much more likely. FillNarInfoCache
(narinfo_cache.go:51, called from internal/shellgen/flake_plan.go:43) uses an
unbounded errgroup one goroutine per package output. Our devbox.lock has 88
x86_64-linux outputs, so devbox opens 88 concurrent requests to cache.nixos.org from
one IP, every time.

The frustrating part: in CI, every one of those paths was already in the local nix
store
from a restored cache. The build could not have needed the network at all.

What solution would you like?

In rough order of value:

  1. Only 404 means absent. Treat 429/5xx/403 as inconclusive. Retry, or
    surface a real error, rather than silently recording the package as missing.
  2. Retry transient statuses with a small backoff.
  3. Skip the probe when the store path already exists locally. This is the CI case,
    and it makes the common path both faster and network-independent. (Same theme as
    #2033.)
  4. Bound the concurrency in FillNarInfoCache, 88 simultaneous requests to one
    host invites rate limiting.
Alternatives you've considered

A wrapper action.

Langage dominant
Go
Étoiles
12.4k
Forks
358
Merge moyen
16 h 9 min
PR mergées (30 j)
31

Préparer son environnement

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de jetify-com/devbox

Toutes les issues de jetify-com/devbox

Issues similaires

Plus d'issues Go

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.