From e9f9003f1be33aa399cfe76bc0c2247cbaa343ec Mon Sep 17 00:00:00 2001 From: sneak Date: Thu, 22 May 2025 07:04:40 -0700 Subject: [PATCH] Improve: Make broadcaster check every 10 seconds for broadcast conditions --- broadcaster.go | 53 ++++++++++++++++++++++++++++++++++---------------- models.go | 1 + 2 files changed, 37 insertions(+), 17 deletions(-) diff --git a/broadcaster.go b/broadcaster.go index 3ebdd0e..834baa0 100644 --- a/broadcaster.go +++ b/broadcaster.go @@ -10,16 +10,17 @@ import ( "time" ) -// broadcaster runs on startup and every hour to select and broadcast the most important article +// broadcaster runs on startup and frequently checks if a broadcast is due func broadcaster(shutdown chan struct{}, dryRun bool) { logInfo("broadcaster", "Starting broadcaster", map[string]interface{}{ - "startupDelay": int(STARTUP_DELAY.Seconds()), - "interval": BROADCAST_INTERVAL.String(), - "dryRun": dryRun, + "startupDelay": int(STARTUP_DELAY.Seconds()), + "checkInterval": BROADCAST_CHECK_INTERVAL.String(), + "broadcastWindow": BROADCAST_INTERVAL.String(), + "dryRun": dryRun, }) // Sleep on startup - logInfo("broadcaster", "Sleeping before first broadcast", map[string]interface{}{ + logInfo("broadcaster", "Sleeping before first broadcast check", map[string]interface{}{ "seconds": int(STARTUP_DELAY.Seconds()), }) select { @@ -30,17 +31,32 @@ func broadcaster(shutdown chan struct{}, dryRun bool) { return } - // Run immediately after initial sleep - checkAndBroadcast(dryRun) + // Track when the last broadcast happened + var lastBroadcastTime time.Time - // Then run on interval - ticker := time.NewTicker(BROADCAST_INTERVAL) + // Run checks frequently + ticker := time.NewTicker(BROADCAST_CHECK_INTERVAL) defer ticker.Stop() for { select { case <-ticker.C: - checkAndBroadcast(dryRun) + now := time.Now() + timeSinceLastBroadcast := now.Sub(lastBroadcastTime) + + // If it's been at least BROADCAST_INTERVAL since last broadcast + // or if we haven't broadcast yet (lastBroadcastTime is zero) + if lastBroadcastTime.IsZero() || timeSinceLastBroadcast >= BROADCAST_INTERVAL { + logInfo("broadcaster", "Broadcast window reached, checking conditions", map[string]interface{}{ + "timeSinceLastBroadcast": timeSinceLastBroadcast.String(), + "requiredInterval": BROADCAST_INTERVAL.String(), + }) + + // Only update lastBroadcastTime if we actually broadcast something + if didBroadcast := checkAndBroadcast(dryRun); didBroadcast { + lastBroadcastTime = now + } + } case <-shutdown: logInfo("broadcaster", "Shutting down broadcaster", nil) return @@ -49,7 +65,8 @@ func broadcaster(shutdown chan struct{}, dryRun bool) { } // checkAndBroadcast checks if there are any unsummarized articles before broadcasting -func checkAndBroadcast(dryRun bool) { +// Returns true if a broadcast was made +func checkAndBroadcast(dryRun bool) bool { // Check if there are any unsummarized articles articles := loadArticles() unsummarizedCount := 0 @@ -65,15 +82,16 @@ func checkAndBroadcast(dryRun bool) { "unsummarizedCount": unsummarizedCount, "totalArticles": len(articles), }) - return + return false } // No unsummarized articles, proceed with broadcast - broadcastWithRedundancyCheck(dryRun) + return broadcastWithRedundancyCheck(dryRun) } // broadcastWithRedundancyCheck attempts to find a non-redundant article to broadcast -func broadcastWithRedundancyCheck(dryRun bool) { +// Returns true if a broadcast was made +func broadcastWithRedundancyCheck(dryRun bool) bool { articles := loadArticles() now := time.Now() cutoff := now.Add(-ARTICLE_FRESHNESS_WINDOW) // Time window for considering articles fresh @@ -90,7 +108,7 @@ func broadcastWithRedundancyCheck(dryRun bool) { logInfo("broadcaster", "No fresh articles found for broadcasting", map[string]interface{}{ "totalArticles": len(articles), }) - return + return false } // Sort by importance @@ -114,7 +132,7 @@ func broadcastWithRedundancyCheck(dryRun bool) { }) // Continue with this candidate despite the error broadcastArticle(candidate, dryRun) - return + return true } if isRedundant { @@ -141,13 +159,14 @@ func broadcastWithRedundancyCheck(dryRun bool) { "candidateNumber": i + 1, }) broadcastArticle(candidate, dryRun) - return + return true } // If we got here, all candidates were redundant logInfo("broadcaster", "All candidates were deemed redundant, no broadcast", map[string]interface{}{ "candidatesChecked": len(candidates), }) + return false } // broadcastArticle broadcasts the chosen article diff --git a/models.go b/models.go index f8df832..32e1f9a 100644 --- a/models.go +++ b/models.go @@ -77,6 +77,7 @@ Here are the articles: RSS_CHECK_INTERVAL = 15 * time.Minute SUMMARIZE_INTERVAL = 10 * time.Second BROADCAST_INTERVAL = 1 * time.Hour + BROADCAST_CHECK_INTERVAL = 10 * time.Second // Interval to check if broadcasting is needed STARTUP_DELAY = 60 * time.Second // Delay before first broadcast BROADCAST_PREPARATION_DELAY = 30 * time.Second // Delay before executing broadcast command ARTICLE_FRESHNESS_WINDOW = 24 * time.Hour // Time window for considering articles fresh