Improve: Make broadcaster check every 10 seconds for broadcast conditions

This commit is contained in:
Jeffrey Paul 2025-05-22 07:04:40 -07:00
parent e769487555
commit e9f9003f1b
2 changed files with 37 additions and 17 deletions

View File

@ -10,16 +10,17 @@ import (
"time" "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) { func broadcaster(shutdown chan struct{}, dryRun bool) {
logInfo("broadcaster", "Starting broadcaster", map[string]interface{}{ logInfo("broadcaster", "Starting broadcaster", map[string]interface{}{
"startupDelay": int(STARTUP_DELAY.Seconds()), "startupDelay": int(STARTUP_DELAY.Seconds()),
"interval": BROADCAST_INTERVAL.String(), "checkInterval": BROADCAST_CHECK_INTERVAL.String(),
"dryRun": dryRun, "broadcastWindow": BROADCAST_INTERVAL.String(),
"dryRun": dryRun,
}) })
// Sleep on startup // 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()), "seconds": int(STARTUP_DELAY.Seconds()),
}) })
select { select {
@ -30,17 +31,32 @@ func broadcaster(shutdown chan struct{}, dryRun bool) {
return return
} }
// Run immediately after initial sleep // Track when the last broadcast happened
checkAndBroadcast(dryRun) var lastBroadcastTime time.Time
// Then run on interval // Run checks frequently
ticker := time.NewTicker(BROADCAST_INTERVAL) ticker := time.NewTicker(BROADCAST_CHECK_INTERVAL)
defer ticker.Stop() defer ticker.Stop()
for { for {
select { select {
case <-ticker.C: 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: case <-shutdown:
logInfo("broadcaster", "Shutting down broadcaster", nil) logInfo("broadcaster", "Shutting down broadcaster", nil)
return return
@ -49,7 +65,8 @@ func broadcaster(shutdown chan struct{}, dryRun bool) {
} }
// checkAndBroadcast checks if there are any unsummarized articles before broadcasting // 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 // Check if there are any unsummarized articles
articles := loadArticles() articles := loadArticles()
unsummarizedCount := 0 unsummarizedCount := 0
@ -65,15 +82,16 @@ func checkAndBroadcast(dryRun bool) {
"unsummarizedCount": unsummarizedCount, "unsummarizedCount": unsummarizedCount,
"totalArticles": len(articles), "totalArticles": len(articles),
}) })
return return false
} }
// No unsummarized articles, proceed with broadcast // No unsummarized articles, proceed with broadcast
broadcastWithRedundancyCheck(dryRun) return broadcastWithRedundancyCheck(dryRun)
} }
// broadcastWithRedundancyCheck attempts to find a non-redundant article to broadcast // 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() articles := loadArticles()
now := time.Now() now := time.Now()
cutoff := now.Add(-ARTICLE_FRESHNESS_WINDOW) // Time window for considering articles fresh 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{}{ logInfo("broadcaster", "No fresh articles found for broadcasting", map[string]interface{}{
"totalArticles": len(articles), "totalArticles": len(articles),
}) })
return return false
} }
// Sort by importance // Sort by importance
@ -114,7 +132,7 @@ func broadcastWithRedundancyCheck(dryRun bool) {
}) })
// Continue with this candidate despite the error // Continue with this candidate despite the error
broadcastArticle(candidate, dryRun) broadcastArticle(candidate, dryRun)
return return true
} }
if isRedundant { if isRedundant {
@ -141,13 +159,14 @@ func broadcastWithRedundancyCheck(dryRun bool) {
"candidateNumber": i + 1, "candidateNumber": i + 1,
}) })
broadcastArticle(candidate, dryRun) broadcastArticle(candidate, dryRun)
return return true
} }
// If we got here, all candidates were redundant // If we got here, all candidates were redundant
logInfo("broadcaster", "All candidates were deemed redundant, no broadcast", map[string]interface{}{ logInfo("broadcaster", "All candidates were deemed redundant, no broadcast", map[string]interface{}{
"candidatesChecked": len(candidates), "candidatesChecked": len(candidates),
}) })
return false
} }
// broadcastArticle broadcasts the chosen article // broadcastArticle broadcasts the chosen article

View File

@ -77,6 +77,7 @@ Here are the articles:
RSS_CHECK_INTERVAL = 15 * time.Minute RSS_CHECK_INTERVAL = 15 * time.Minute
SUMMARIZE_INTERVAL = 10 * time.Second SUMMARIZE_INTERVAL = 10 * time.Second
BROADCAST_INTERVAL = 1 * time.Hour 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 STARTUP_DELAY = 60 * time.Second // Delay before first broadcast
BROADCAST_PREPARATION_DELAY = 30 * time.Second // Delay before executing broadcast command BROADCAST_PREPARATION_DELAY = 30 * time.Second // Delay before executing broadcast command
ARTICLE_FRESHNESS_WINDOW = 24 * time.Hour // Time window for considering articles fresh ARTICLE_FRESHNESS_WINDOW = 24 * time.Hour // Time window for considering articles fresh