From b4dacbef39b5bfc1214fd092b3654c80a21b1be3 Mon Sep 17 00:00:00 2001 From: Aditya Choudhari Date: Fri, 6 Mar 2026 14:20:13 -0800 Subject: [PATCH] perf: get entity by id --- .../controllers/desiredrelease/adapters.go | 4 + .../svc/controllers/desiredrelease/getters.go | 1 + .../desiredrelease/getters_postgres.go | 74 +++++++++++++++++++ .../variableresolver/resolve.go | 18 ++--- .../variableresolver/resolve_test.go | 9 +++ .../test/controllers/harness/mocks.go | 11 +++ 6 files changed, 106 insertions(+), 11 deletions(-) diff --git a/apps/workspace-engine/svc/controllers/desiredrelease/adapters.go b/apps/workspace-engine/svc/controllers/desiredrelease/adapters.go index a3ab27cb2..5a41a0bba 100644 --- a/apps/workspace-engine/svc/controllers/desiredrelease/adapters.go +++ b/apps/workspace-engine/svc/controllers/desiredrelease/adapters.go @@ -56,6 +56,10 @@ func (a *variableResolverAdapter) LoadCandidates(ctx context.Context, workspaceI return a.getter.LoadCandidates(ctx, workspaceID, entityType) } +func (a *variableResolverAdapter) GetEntityByID(ctx context.Context, entityID uuid.UUID, entityType string) (*eval.EntityData, error) { + return a.getter.GetEntityByID(ctx, entityID, entityType) +} + func buildRelease(rt *ReleaseTarget, version *oapi.DeploymentVersion, variables map[string]oapi.LiteralValue) *oapi.Release { return &oapi.Release{ ReleaseTarget: oapi.ReleaseTarget{ diff --git a/apps/workspace-engine/svc/controllers/desiredrelease/getters.go b/apps/workspace-engine/svc/controllers/desiredrelease/getters.go index d9cf0ae73..9c495cf15 100644 --- a/apps/workspace-engine/svc/controllers/desiredrelease/getters.go +++ b/apps/workspace-engine/svc/controllers/desiredrelease/getters.go @@ -28,4 +28,5 @@ type Getter interface { // Realtime relationship resolution GetRelationshipRules(ctx context.Context, workspaceID uuid.UUID) ([]eval.Rule, error) LoadCandidates(ctx context.Context, workspaceID uuid.UUID, entityType string) ([]eval.EntityData, error) + GetEntityByID(ctx context.Context, entityID uuid.UUID, entityType string) (*eval.EntityData, error) } diff --git a/apps/workspace-engine/svc/controllers/desiredrelease/getters_postgres.go b/apps/workspace-engine/svc/controllers/desiredrelease/getters_postgres.go index 8864dce09..edf575648 100644 --- a/apps/workspace-engine/svc/controllers/desiredrelease/getters_postgres.go +++ b/apps/workspace-engine/svc/controllers/desiredrelease/getters_postgres.go @@ -306,6 +306,80 @@ FROM environment WHERE workspace_id = $1 ` +const getResourceByIDSQL = ` +SELECT id, workspace_id, name, kind, version, identifier, + provider_id, config, metadata, created_at, updated_at +FROM resource +WHERE id = $1 AND deleted_at IS NULL +` + +const getDeploymentByIDSQL = ` +SELECT id, workspace_id, name, description, job_agent_id, job_agent_config, metadata +FROM deployment +WHERE id = $1 +` + +const getEnvironmentByIDSQL = ` +SELECT id, workspace_id, name, description, metadata, created_at +FROM environment +WHERE id = $1 +` + +func (g *PostgresGetter) GetEntityByID(ctx context.Context, entityID uuid.UUID, entityType string) (*eval.EntityData, error) { + pool := db.GetPool(ctx) + + var query string + var buildMap func(values []any) map[string]any + switch entityType { + case "resource": + query = getResourceByIDSQL + buildMap = rowToResourceMap + case "deployment": + query = getDeploymentByIDSQL + buildMap = rowToDeploymentMap + case "environment": + query = getEnvironmentByIDSQL + buildMap = rowToEnvironmentMap + default: + return nil, fmt.Errorf("unknown entity type: %s", entityType) + } + + rows, err := pool.Query(ctx, query, entityID) + if err != nil { + return nil, fmt.Errorf("query %s by id %s: %w", entityType, entityID, err) + } + defer rows.Close() + + if !rows.Next() { + if err := rows.Err(); err != nil { + return nil, fmt.Errorf("iterate %s row: %w", entityType, err) + } + return nil, fmt.Errorf("%s with id %s not found", entityType, entityID) + } + + values, err := rows.Values() + if err != nil { + return nil, fmt.Errorf("scan %s row: %w", entityType, err) + } + + id, ok := values[0].([16]byte) + if !ok { + return nil, fmt.Errorf("invalid id type for %s %s", entityType, entityID) + } + + wsID, ok := values[1].([16]byte) + if !ok { + return nil, fmt.Errorf("invalid workspace_id type for %s %s", entityType, entityID) + } + + return &eval.EntityData{ + ID: uuid.UUID(id), + WorkspaceID: uuid.UUID(wsID), + EntityType: entityType, + Raw: buildMap(values), + }, nil +} + func rowToResourceMap(values []any) map[string]any { m := map[string]any{"type": "resource"} if len(values) > 0 { diff --git a/apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve.go b/apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve.go index cec6903aa..a7cebe9de 100644 --- a/apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve.go +++ b/apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve.go @@ -27,6 +27,7 @@ type Getter interface { GetResourceVariables(ctx context.Context, resourceID string) (map[string]oapi.ResourceVariable, error) GetRelationshipRules(ctx context.Context, workspaceID uuid.UUID) ([]eval.Rule, error) LoadCandidates(ctx context.Context, workspaceID uuid.UUID, entityType string) ([]eval.EntityData, error) + GetEntityByID(ctx context.Context, entityID uuid.UUID, entityType string) (*eval.EntityData, error) } // Scope carries the already-resolved entities for the release target so the @@ -183,21 +184,16 @@ func (r *realtimeResolver) ResolveRelated(ctx context.Context, reference string) relatedType = m.FromEntityType } - candidates, err := r.getter.LoadCandidates(ctx, r.workspaceID, relatedType) + entity, err := r.getter.GetEntityByID(ctx, relatedID, relatedType) if err != nil { - return nil, fmt.Errorf("load candidate for matched entity %s: %w", relatedID, err) + return nil, fmt.Errorf("get matched entity %s: %w", relatedID, err) } - for i := range candidates { - if candidates[i].ID == relatedID { - re, err := entityDataToRelatableEntity(&candidates[i]) - if err != nil { - return nil, fmt.Errorf("convert matched entity: %w", err) - } - result = append(result, re) - break - } + re, err := entityDataToRelatableEntity(entity) + if err != nil { + return nil, fmt.Errorf("convert matched entity: %w", err) } + result = append(result, re) } return result, nil diff --git a/apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve_test.go b/apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve_test.go index 422d3e97c..c456b27fa 100644 --- a/apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve_test.go +++ b/apps/workspace-engine/svc/controllers/desiredrelease/variableresolver/resolve_test.go @@ -2,6 +2,7 @@ package variableresolver import ( "context" + "fmt" "testing" "workspace-engine/pkg/oapi" @@ -47,6 +48,14 @@ func (m *mockGetter) GetRelationshipRules(_ context.Context, _ uuid.UUID) ([]eva func (m *mockGetter) LoadCandidates(_ context.Context, _ uuid.UUID, entityType string) ([]eval.EntityData, error) { return m.candidates[entityType], nil } +func (m *mockGetter) GetEntityByID(_ context.Context, entityID uuid.UUID, entityType string) (*eval.EntityData, error) { + for i := range m.candidates[entityType] { + if m.candidates[entityType][i].ID == entityID { + return &m.candidates[entityType][i], nil + } + } + return nil, fmt.Errorf("%s with id %s not found", entityType, entityID) +} // --------------------------------------------------------------------------- // helpers diff --git a/apps/workspace-engine/test/controllers/harness/mocks.go b/apps/workspace-engine/test/controllers/harness/mocks.go index c71097de2..773eddc3c 100644 --- a/apps/workspace-engine/test/controllers/harness/mocks.go +++ b/apps/workspace-engine/test/controllers/harness/mocks.go @@ -141,6 +141,17 @@ func (g *DesiredReleaseGetter) LoadCandidates(_ context.Context, _ uuid.UUID, en return nil, nil } +func (g *DesiredReleaseGetter) GetEntityByID(_ context.Context, entityID uuid.UUID, entityType string) (*eval.EntityData, error) { + if g.Candidates != nil { + for i := range g.Candidates[entityType] { + if g.Candidates[entityType][i].ID == entityID { + return &g.Candidates[entityType][i], nil + } + } + } + return nil, fmt.Errorf("%s with id %s not found", entityType, entityID) +} + // DesiredReleaseSetter implements desiredrelease.Setter. // When JobDispatchQueue is set, it also enqueues a job-dispatch item for // each release that is set, bridging the desired-release and job-dispatch