feat(workload): switch buildActiveImagesSet to containers index

First consumer migration off the instances table. The image
prune logic now walks the normalized containers.image_ref
column directly — one DB pass against a single table instead
of joining instances against projects to reconstruct the full
"image:tag" string. Demonstrates the consumer-switch pattern
the remaining read sites (proxies, stale scanner, webhook
matcher) will follow.

The legacy `projects []store.Project` parameter is kept on the
function signature for now so call sites don't change in this
commit; the underscore-discard in the body makes it explicit
that it's no longer load-bearing.
This commit is contained in:
2026-05-09 13:47:20 +03:00
parent af82be3fb8
commit 7f2d1bdae1
+13 -17
View File
@@ -245,28 +245,24 @@ func sanitizeDockerLogLine(line string) string {
} }
// buildActiveImagesSet returns the set of "image:tag" strings currently used // buildActiveImagesSet returns the set of "image:tag" strings currently used
// by any instance, computed in a single DB pass instead of N×K queries. // by any container, computed in a single DB pass against the normalized
// Returning an error (rather than swallowing) prevents prune logic from // containers index. Returning an error (rather than swallowing) prevents
// treating a transient DB failure as "nothing is active". // prune logic from treating a transient DB failure as "nothing is active".
func buildActiveImagesSet(st *store.Store, projects []store.Project) (map[string]bool, error) { func buildActiveImagesSet(st *store.Store, projects []store.Project) (map[string]bool, error) {
imageByProject := make(map[string]string, len(projects)) // `projects` is unused now — kept in the signature for back-compat with
for _, p := range projects { // callers that already happen to have the slice. The image_ref column
imageByProject[p.ID] = p.Image // holds the full "image:tag" string written by the deployer.
} _ = projects
instances, err := st.ListAllInstances() containers, err := st.ListContainers(store.ContainerFilter{})
if err != nil { if err != nil {
return nil, fmt.Errorf("list instances: %w", err) return nil, fmt.Errorf("list containers: %w", err)
} }
active := make(map[string]bool, len(instances)) active := make(map[string]bool, len(containers))
for _, inst := range instances { for _, c := range containers {
if inst.ImageTag == "" { if c.ImageRef == "" {
continue continue
} }
image := imageByProject[inst.ProjectID] active[c.ImageRef] = true
if image == "" {
continue
}
active[image+":"+inst.ImageTag] = true
} }
return active, nil return active, nil
} }