Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

sandbox cache: StartRemoving state transition not broadcast, all allocations see stale Running state

Aperta Adatta ai principianti
#3,595 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 3 giorni

@AdaAibaby ci sta già lavorando.

Dal 22/8/2026.

  • #3596 di @AdaAibaby — aperta

Valutazione

Difficoltà
2/5
Tempo stimato
1-3 ore
Idoneità per principianti
86/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
go, redis
Ambito
backend, databases

Direzione di ricerca

Inizia in packages/api/internal/sandbox/storage/redis/state_change.go, in StartRemoving, quindi confronta la gestione delle transizioni con il pattern di pubblicazione di Update() in operations.go. Segui il dispatch di subscription_manager.go per verificare che la cache riceva l’evento di aggiornamento del sandbox; il lavoro è completato quando la cache riflette il nuovo stato della transizione dopo StartRemoving senza modificare il comportamento esistente del callback.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

When StartRemoving atomically writes a state transition to Redis (e.g. Running → Killing), it never calls publishSandboxEvent. The per-allocation in-process sandbox cache (introduced in #3593) therefore never learns about the new state, and every allocation continues to serve the old Running state from memory until the sandbox is eventually deleted and a remove event arrives.

Code Path

Step 1 — Lua script writes new state to Redis, but no event is published
// state_change.go
updated := sbx
updated.State = newState                       // e.g. Killing

written, err := startTransitionScript.Run(ctx, s.redisClient,
    []string{key, transitionKey, resultKey},
    newData, transitionID, ...)                // Redis now has State=Killing

// StartRemoving returns here — no publishSandboxEvent call
return updated, false, s.createCallback(...), nil
Step 2 — createCallback publishes only a routing key, not a sandboxEvent
// state_change.go — createCallback
s.publisher.Publish(cbCtx, getTransitionRoutingKey(teamID.String(), sandboxID, transitionID))
// payload: "lock:sandbox:storage:...:transition:<uuid>"
Step 3 — dispatch routes the payload to waiters, never to cache.apply
// subscription_manager.go
func (m *subscriptionManager) dispatch(payload string) {
    if isSandboxEvent(payload) {   // strings.HasPrefix(payload, "{") → false for routing keys
        m.cache.apply(evt)         // never reached
        return
    }
    // falls through to waiter fan-out
}

Impact

Between startTransitionScript.Run() and the final Remove() call (which does publish a remove event), every allocation returns State = Running from TeamItems for a sandbox that Redis already has as Killing or Pausing. For transient transitions, restoreToRunning calls Update() which publishes correctly, but the first half of the round-trip remains invisible to the cache.

Concretely:

  • TeamItems(states: [Running]) returns sandboxes that are mid-removal — callers may act on them incorrectly.
  • Metrics and user-facing sandbox list show inflated Running counts during high-eviction periods.

Fix

In StartRemoving, after startTransitionScript.Run() succeeds, broadcast the updated sandbox:

s.publisher.publishSandboxEvent(ctx, sandboxEvent{
    Op:      sandboxEventOpUpdate,
    Sandbox: &updated,
})

This mirrors exactly what Update() does in operations.go. dispatch() will call cache.apply({update, updated}), replacing the cached entry with the correct state.

The createCallback path does not need a separate publish because:

  • For permanent removals (TransitionExpires), the subsequent Remove() call already publishes a remove event.
  • For transient transitions, restoreToRunning calls Update() which already publishes an update event.

Related

  • #3593 — introduces the per-allocation cache that this change affects
  • packages/api/internal/sandbox/storage/redis/state_change.go
  • packages/api/internal/sandbox/storage/redis/operations.go (reference: correct publish pattern in Update())
Lingua principale
Go
Stelle
1.7k
Fork
458
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Preparare l'ambiente

Apri in Codespaces

Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di e2b-dev/runtime

Tutte le issue di e2b-dev/runtime

Issue simili

Altre issue su Go

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.