main: bound startup sweep with context timeout
Sweep() used to run synchronously at startup without any time bound. On a large uploads directory this can block the server for 30s or more, keeping /healthz returning 503 while the reaper works. Add a context timeout so startup continues if the sweep cannot finish within budget. The timeout is set to 5 seconds: long enough to clear typical leftover state, short enough that a stuck sweep will not meaningfully delay health checks or startup readiness. Change Store.Sweep to accept a context.Context and check ctx.Err() at the top of each iteration. If the context is cancelled or times out, Sweep returns the files deleted so far and ctx.Err(). Add TestStore_Sweep_HonorsContextCancel to ensure a cancelled context causes Sweep to exit early instead of running to completion. Deliberately unchanged: there is still no periodic reaper. The server only sweeps once at startup; this change just bounds that single sweep. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
package uploads
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
@@ -160,7 +161,7 @@ func (s *Store) Validate(absPath string) (string, error) {
|
||||
// Sweep deletes data files (and their sidecars) whose uploaded_at is older
|
||||
// than ttl, as well as orphan sidecars that have no matching data file. For
|
||||
// data files whose sidecar is missing, the file's mtime is used as a fallback.
|
||||
func (s *Store) Sweep(ttl time.Duration) (deleted int, err error) {
|
||||
func (s *Store) Sweep(ctx context.Context, ttl time.Duration) (deleted int, err error) {
|
||||
entries, err := os.ReadDir(s.Root)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("uploads: read root: %w", err)
|
||||
@@ -197,6 +198,9 @@ func (s *Store) Sweep(ttl time.Duration) (deleted int, err error) {
|
||||
cutoff := time.Now().Add(-ttl)
|
||||
|
||||
for fileID, it := range items {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return deleted, err
|
||||
}
|
||||
dataPath := filepath.Join(s.Root, fileID)
|
||||
metaPath := dataPath + ".meta.json"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user