diff options
| author | Bobby <[email protected]> | 2025-05-09 06:58:25 +0530 |
|---|---|---|
| committer | Bobby <[email protected]> | 2025-05-09 06:58:25 +0530 |
| commit | 31dddf48dbb5d227e571ed9459aa437af3b0d1d3 (patch) | |
| tree | df271a958f35abd0cd46550078053e0d3585b195 /tasks | |
| parent | 596ef846c97d9373ddda711dabfde9720b6931d7 (diff) | |
| download | metachan-31dddf48dbb5d227e571ed9459aa437af3b0d1d3.tar.xz metachan-31dddf48dbb5d227e571ed9459aa437af3b0d1d3.zip | |
fixed anime updater
Diffstat (limited to 'tasks')
| -rw-r--r-- | tasks/anime_update.task.go | 88 |
1 files changed, 75 insertions, 13 deletions
diff --git a/tasks/anime_update.task.go b/tasks/anime_update.task.go index 4d37fbc..f60d435 100644 --- a/tasks/anime_update.task.go +++ b/tasks/anime_update.task.go @@ -2,6 +2,7 @@ package tasks import ( "fmt" + "metachan/config" "metachan/database" "metachan/entities" "metachan/services/anime" @@ -18,6 +19,12 @@ const ( // MaxConcurrentUpdates limits the number of concurrent anime updates MaxConcurrentUpdates = 5 + + // MaxConcurrentSQLiteUpdates limits concurrent updates for SQLite to prevent locks + MaxConcurrentSQLiteUpdates = 1 + + // UpdateInterval defines how often an anime should be updated even without specific triggers + UpdateInterval = 6 * time.Hour ) // animeUpdateJob represents a single anime update job @@ -38,6 +45,7 @@ func AnimeUpdate() error { result := database.DB. Where("airing = ?", true). Preload("NextAiringEpisode"). + Preload("AiringSchedule"). Find(&airingSeries) if result.Error != nil { @@ -56,14 +64,32 @@ func AnimeUpdate() error { // Get current timestamp currentTime := time.Now().Unix() + // Log the current time for debugging + logger.Log(fmt.Sprintf("Current timestamp: %d (%s)", + currentTime, time.Unix(currentTime, 0).Format(time.RFC3339)), logger.LogOptions{ + Level: logger.Debug, + Prefix: "AnimeUpdate", + }) + // Create a channel for jobs jobs := make(chan animeUpdateJob, len(airingSeries)) + // Determine max concurrency based on database type + maxWorkers := MaxConcurrentUpdates + if config.Config.DatabaseDriver == types.SQLite { + maxWorkers = MaxConcurrentSQLiteUpdates + logger.Log(fmt.Sprintf("Using reduced concurrency (%d workers) for SQLite database", + maxWorkers), logger.LogOptions{ + Level: logger.Debug, + Prefix: "AnimeUpdate", + }) + } + // Create a wait group to wait for all workers to finish var wg sync.WaitGroup // Create workers - for i := 0; i < MaxConcurrentUpdates; i++ { + for i := 0; i < maxWorkers; i++ { wg.Add(1) go func(workerID int) { defer wg.Done() @@ -88,27 +114,47 @@ func AnimeUpdate() error { needsUpdate := false reason := "" + // Log details about this particular anime for debugging + logger.Log(fmt.Sprintf("Checking anime: %s (ID: %d)", + series.TitleRomaji, series.MALID), logger.LogOptions{ + Level: logger.Debug, + Prefix: "AnimeUpdate", + }) + // If there's no next airing episode data, we should update - if series.NextAiringEpisode == nil { + if series.NextAiringEpisode == nil || series.NextAiringEpisode.AiringAt == 0 { needsUpdate = true reason = "missing next episode data" - } else { - // Check if the next episode has already aired - if int64(series.NextAiringEpisode.AiringAt) < currentTime { - needsUpdate = true - reason = fmt.Sprintf("episode %d aired at %d (current: %d)", - series.NextAiringEpisode.Episode, - series.NextAiringEpisode.AiringAt, - currentTime) - } + } else if int64(series.NextAiringEpisode.AiringAt) <= currentTime { + // If the next episode should have aired already, update to get fresh data + needsUpdate = true + reason = "next episode already aired" + } + + // Check if the anime was last updated more than the update interval ago + if !needsUpdate && !series.LastUpdated.IsZero() && time.Since(series.LastUpdated) > UpdateInterval { + needsUpdate = true + reason = fmt.Sprintf("regular update (last updated %s ago)", + time.Since(series.LastUpdated).Round(time.Second)) } - // Skip if no update is needed + // Log update decision if !needsUpdate { + logger.Log(fmt.Sprintf("Skipping update for %s (ID: %d) - no update needed", + series.TitleRomaji, series.MALID), logger.LogOptions{ + Level: logger.Debug, + Prefix: "AnimeUpdate", + }) continue } // Add the job to the queue + logger.Log(fmt.Sprintf("Queueing update for %s (ID: %d) - Reason: %s", + series.TitleRomaji, series.MALID, reason), logger.LogOptions{ + Level: logger.Debug, + Prefix: "AnimeUpdate", + }) + jobs <- animeUpdateJob{ series: series, reason: reason, @@ -163,6 +209,7 @@ func updateAnime(animeService *anime.Service, series entities.CachedAnime, reaso oldCachedAnime, err := database.GetCachedAnimeByMALID(series.MALID) if err != nil || shouldSaveUpdate(oldCachedAnime, updatedAnime) { + saved = true // Save the updated data to cache if err := database.SaveAnimeToCache(updatedAnime); err != nil { logger.Log(fmt.Sprintf("Failed to save updated data for MALID %d: %v", series.MALID, err), logger.LogOptions{ @@ -171,7 +218,6 @@ func updateAnime(animeService *anime.Service, series entities.CachedAnime, reaso }) return } - saved = true } status := "skipped (no significant changes)" @@ -211,6 +257,22 @@ func shouldSaveUpdate(oldAnime *entities.CachedAnime, newAnime *types.Anime) boo return true } + // Check if airing status changed + if oldAnimeConverted.Airing != newAnime.Airing || + oldAnimeConverted.Status != newAnime.Status { + return true + } + + // Check if the total episode count has changed + if oldAnimeConverted.Episodes.Total != newAnime.Episodes.Total { + return true + } + + // Check if number of episodes in the airing schedule changed + if len(oldAnimeConverted.AiringSchedule) != len(newAnime.AiringSchedule) { + return true + } + // No significant changes detected return false } |
