Unverified Commit 9baa0a10 authored by Lemon-miaow's avatar Lemon-miaow
Browse files

fix(registrygate): 启动后先等写入静默再开放 GC 窗口

parent 151c9d2e
Loading
Loading
Loading
Loading
+4 −0
Changes for internal/registrygate/gate.go: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -95,6 +95,10 @@ func New(upstream *url.URL, tokens map[string]string, log *slog.Logger) *Gate {
	g.health = &http.Client{Timeout: 3 * time.Second}
	g.maint.now = time.Now
	g.maint.quiet = DefaultQuiet
	// A gate that just started cannot tell whether a push was mid-way through the
	// previous one, and the installer pushes right after the registry rolls out:
	// count the start as a write, so the first window waits for quiet too.
	g.maint.lastWrite = g.maint.now()
	return g
}

+19 −0
Changes for internal/registrygate/maint_test.go: 19 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ func newMaintGate(t *testing.T) (*Gate, *httptest.Server, *httptest.Server, *ups
	}, nil)
	clk := &clock{t: time.Date(2026, 9, 24, 3, 0, 0, 0, time.UTC)}
	g.maint.now = clk.now
	g.maint.lastWrite = time.Time{}
	gs := httptest.NewServer(g)
	t.Cleanup(gs.Close)
	ms := httptest.NewServer(g.MaintHandler())
@@ -276,3 +277,21 @@ func TestManifestIndexListsUntaggedRevisions(t *testing.T) {
		}
	}
}

// A gate that just started grants no window before a quiet period has passed:
// the installer pushes right after the registry rolls out.
func TestReadOnlyWindowWaitsAfterStart(t *testing.T) {
	up := httptest.NewServer(http.NotFoundHandler())
	t.Cleanup(up.Close)
	target, _ := url.Parse(up.URL)
	g := New(target, nil, nil)
	ms := httptest.NewServer(g.MaintHandler())
	t.Cleanup(ms.Close)
	if code := post(t, ms, "/readonly?lease=60"); code != http.StatusConflict {
		t.Fatalf("read-only window right after start = %d, want 409", code)
	}
	g.SetQuiet(0)
	if code := post(t, ms, "/readonly?lease=60"); code != http.StatusOK {
		t.Fatalf("read-only window once quiet = %d, want 200", code)
	}
}