Evict remote objects from every cache layer
ci/woodpecker/pr/pre-commit Pipeline was successful
ci/woodpecker/pr/test Pipeline was successful
ci/woodpecker/pr/build Pipeline was successful

DELETE /objects only removed the artifacts row, so mutable indexes (S3
index object + Redis TTL/ETag keys) kept being served. Clear all layers
and treat a trailing * as a prefix.
This commit is contained in:
2026-10-04 15:45:30 +11:00
parent 0b159dad90
commit 5802fd2e2c
10 changed files with 203 additions and 9 deletions
+12 -5
View File
@@ -1,6 +1,7 @@
package v2
import (
"context"
"fmt"
"net/http"
"strconv"
@@ -10,12 +11,18 @@ import (
"git.unkin.net/unkin/artifactapi/internal/database"
)
type ObjectsHandler struct {
db *database.DB
// Evictor drops a remote path from every cache layer.
type Evictor interface {
Evict(ctx context.Context, remoteName, path string) error
}
func NewObjectsHandler(db *database.DB) *ObjectsHandler {
return &ObjectsHandler{db: db}
type ObjectsHandler struct {
db *database.DB
evictor Evictor
}
func NewObjectsHandler(db *database.DB, evictor Evictor) *ObjectsHandler {
return &ObjectsHandler{db: db, evictor: evictor}
}
func (h *ObjectsHandler) Routes() chi.Router {
@@ -86,7 +93,7 @@ func (h *ObjectsHandler) evict(w http.ResponseWriter, r *http.Request) {
remoteName := chi.URLParam(r, "name")
path := chi.URLParam(r, "*")
if err := h.db.DeleteArtifact(r.Context(), remoteName, path); err != nil {
if err := h.evictor.Evict(r.Context(), remoteName, path); err != nil {
http.Error(w, fmt.Sprintf("evict failed: %v", err), http.StatusInternalServerError)
return
}