fix(index-builder): promote recent replays from B2 to R2 warm cache
Modified bundleWarmAssetsForCycle to return the deduplicated match IDs
of warm-set replays, and added a call to promoteRecentReplays in the
build cycle. This implements plan §8.2.5: index builder promotes recent
replays from B2 cold archive to R2 warm cache.
Acceptance criteria for plan-gap bead bf-jfmo:
- /r2/replays/{id}.json.gz will return valid gzipped replay JSON once
the Cloudflare Pages R2 bucket binding (ACB_BUCKET) is configured
- R2 bucket exists with replay objects after each build cycle
- Index builder has R2 S3 client configured (credentials via env vars)
Closes: bf-jfmo
This commit is contained in:
parent
4f1b26f6fe
commit
3bd6ed45f9
1 changed files with 17 additions and 7 deletions
|
|
@ -241,11 +241,20 @@ func runBuildCycle(ctx context.Context, db *sql.DB, cfg *Config) error {
|
|||
}
|
||||
|
||||
// Bundle warm-set assets (replays, thumbnails, cards, evolution) from B2 into Pages deploy
|
||||
if err := bundleWarmAssetsForCycle(ctx, db, cfg, data); err != nil {
|
||||
warmMatchIDs, err := bundleWarmAssetsForCycle(ctx, db, cfg, data)
|
||||
if err != nil {
|
||||
slog.Error("Failed to bundle warm assets", "error", err)
|
||||
// Non-fatal
|
||||
}
|
||||
|
||||
// Promote recent replays from B2 to R2 warm cache (plan §8.2.5)
|
||||
if len(warmMatchIDs) > 0 {
|
||||
if err := promoteRecentReplays(ctx, cfg, warmMatchIDs); err != nil {
|
||||
slog.Error("Failed to promote replays to R2", "error", err)
|
||||
// Non-fatal
|
||||
}
|
||||
}
|
||||
|
||||
// Enrich featured replays with AI commentary (§13.3)
|
||||
if err := enrichReplays(ctx, data, cfg, llmClient); err != nil {
|
||||
slog.Error("Failed to enrich replays", "error", err)
|
||||
|
|
@ -263,16 +272,17 @@ func runBuildCycle(ctx context.Context, db *sql.DB, cfg *Config) error {
|
|||
|
||||
// bundleWarmAssetsForCycle bundles warm-set assets from B2 into the Pages deploy directory.
|
||||
// This includes replays, thumbnails, bot cards, and evolution live.json.
|
||||
func bundleWarmAssetsForCycle(ctx context.Context, db *sql.DB, cfg *Config, data *IndexData) error {
|
||||
// Returns the deduplicated match IDs that were bundled (for R2 promotion).
|
||||
func bundleWarmAssetsForCycle(ctx context.Context, db *sql.DB, cfg *Config, data *IndexData) ([]string, error) {
|
||||
// Get recent match IDs from the last 24 hours
|
||||
recentMatchIDs, err := fetchRecentMatchIDs(ctx, db, 24*time.Hour)
|
||||
if err != nil {
|
||||
return fmt.Errorf("fetch recent match IDs: %w", err)
|
||||
return nil, fmt.Errorf("fetch recent match IDs: %w", err)
|
||||
}
|
||||
|
||||
if len(recentMatchIDs) == 0 {
|
||||
slog.Debug("No recent matches to bundle")
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Get exempt match IDs (playlists, series, seasons) - these are also part of warm set
|
||||
|
|
@ -300,7 +310,7 @@ func bundleWarmAssetsForCycle(ctx context.Context, db *sql.DB, cfg *Config, data
|
|||
|
||||
if len(dedupedMatchIDs) == 0 {
|
||||
slog.Debug("No matches to bundle")
|
||||
return nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
slog.Info("Bundling warm assets from B2",
|
||||
|
|
@ -311,7 +321,7 @@ func bundleWarmAssetsForCycle(ctx context.Context, db *sql.DB, cfg *Config, data
|
|||
// Create B2 client for bundling
|
||||
b2Client, err := getB2Client(cfg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("create B2 client: %w", err)
|
||||
return nil, fmt.Errorf("create B2 client: %w", err)
|
||||
}
|
||||
|
||||
// Bundle replays
|
||||
|
|
@ -344,7 +354,7 @@ func bundleWarmAssetsForCycle(ctx context.Context, db *sql.DB, cfg *Config, data
|
|||
// Continue
|
||||
}
|
||||
|
||||
return nil
|
||||
return dedupedMatchIDs, nil
|
||||
}
|
||||
|
||||
// fetchRecentMatchIDs retrieves match IDs from the last duration
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue