diff --git a/cmd/acb-index-builder/main.go b/cmd/acb-index-builder/main.go index f06ab37..7444034 100644 --- a/cmd/acb-index-builder/main.go +++ b/cmd/acb-index-builder/main.go @@ -10,6 +10,7 @@ import ( "syscall" "time" + "github.com/aicodebattle/acb/metrics" _ "github.com/lib/pq" ) @@ -47,6 +48,10 @@ func main() { "database", cfg.PostgresDatabase, ) + // Start internal metrics server (separate port for Prometheus scraping) + metricsSrv := metrics.StartServer() + defer metricsSrv.Close() + // Create output directory if err := os.MkdirAll(cfg.OutputDir, 0755); err != nil { slog.Error("Failed to create output directory", "error", err, "path", cfg.OutputDir) @@ -79,6 +84,7 @@ func main() { buildCount++ slog.Info("Starting build cycle", "count", buildCount) + buildStart := time.Now() buildCtx, buildCancel := context.WithTimeout(context.Background(), cfg.BuildTimeout) if err := runBuildCycle(buildCtx, db, cfg); err != nil { slog.Error("Build cycle failed", "error", err) @@ -86,6 +92,7 @@ func main() { slog.Info("Build cycle completed", "count", buildCount) } buildCancel() + metrics.IndexBuildDuration.Observe(time.Since(buildStart).Seconds()) // Deploy every N cycles if buildCount%cfg.DeployInterval == 0 { diff --git a/cmd/acb-index-builder/rivalry_test.go b/cmd/acb-index-builder/rivalry_test.go index d49aad6..811c53b 100644 --- a/cmd/acb-index-builder/rivalry_test.go +++ b/cmd/acb-index-builder/rivalry_test.go @@ -308,32 +308,50 @@ func TestComputeRivalries_MultiPlayerSkipped(t *testing.T) { func TestComputeRivalries_RecencyBoost(t *testing.T) { now := time.Now() - // Pair 1: all matches in the last week (high recency) + // Pair 1: all matches in the last week (high recency), balanced 5-5 split var recentMatches []MatchData - for i := 0; i < 10; i++ { + for i := 0; i < 5; i++ { recentMatches = append(recentMatches, MatchData{ - ID: fmt.Sprintf("recent_%d", i), + ID: fmt.Sprintf("recent_a_%d", i), WinnerID: "bot1", - PlayedAt: now.Add(-time.Duration(i*12) * time.Hour), // within last 5 days + PlayedAt: now.Add(-time.Duration(i*12) * time.Hour), Participants: []ParticipantData{ {BotID: "bot1", Score: 3, Won: true}, {BotID: "bot2", Score: 2, Won: false}, }, }) + recentMatches = append(recentMatches, MatchData{ + ID: fmt.Sprintf("recent_b_%d", i), + WinnerID: "bot2", + PlayedAt: now.Add(-time.Duration(i*12+6) * time.Hour), + Participants: []ParticipantData{ + {BotID: "bot1", Score: 2, Won: false}, + {BotID: "bot2", Score: 3, Won: true}, + }, + }) } - // Pair 2: all matches 6 months ago (low recency) + // Pair 2: all matches 6 months ago (low recency), balanced 5-5 split var oldMatches []MatchData - for i := 0; i < 10; i++ { + for i := 0; i < 5; i++ { oldMatches = append(oldMatches, MatchData{ - ID: fmt.Sprintf("old_%d", i), + ID: fmt.Sprintf("old_a_%d", i), WinnerID: "bot3", - PlayedAt: now.Add(-180*24*time.Hour - time.Duration(i)*time.Hour), // ~6 months ago + PlayedAt: now.Add(-180*24*time.Hour - time.Duration(i)*time.Hour), Participants: []ParticipantData{ {BotID: "bot3", Score: 3, Won: true}, {BotID: "bot4", Score: 2, Won: false}, }, }) + oldMatches = append(oldMatches, MatchData{ + ID: fmt.Sprintf("old_b_%d", i), + WinnerID: "bot4", + PlayedAt: now.Add(-180*24*time.Hour - time.Duration(i+5)*time.Hour), + Participants: []ParticipantData{ + {BotID: "bot3", Score: 2, Won: false}, + {BotID: "bot4", Score: 3, Won: true}, + }, + }) } allMatches := append(recentMatches, oldMatches...)