public bool ProcessNetworkCache(TwitNetworkCache requestCache, ListEpisodesResponse listAllEpisodes) { foreach (Episode episode in listAllEpisodes.episodes) { foreach (Show show in episode._embedded.shows) { TwitNetworkShowCache thisShow; if (requestCache.ContainsShow(show.id)) { _logger.Debug("Show {0} is already in the network cache", show.label); thisShow = requestCache.GetCacheEntry(show.id); } else { if (requestCache.TryAdd(show)) { _logger.Debug("Show {0} has been added to the network cache", show.label); thisShow = requestCache.GetCacheEntry(show.id); } else { _logger.Warn("Show {0} cannot be added to the network cache", show.label); continue; } } if (thisShow.HasEpisode(episode.id)) { _logger.Debug("{0} episode {1} ({2}) is already in the network cache", show.label, episode.episodeNumber, episode.label); } else { _logger.Debug("{0} episode {1} ({2}) has been added to the cache", show.label, episode.episodeNumber, episode.label); thisShow.AddEpisode(episode); } } } return(true); }
/// <summary> /// Chain populates the episode cache. /// </summary> /// <param name="requestCache">An instance of the TWiT network cache</param> /// <param name="requestDays">Number of day to request in the API call</param> /// <param name="requestLimit">Number of API calls allowed in a minute</param> /// <param name="cancellationToken"></param> /// <returns>If a successful cache refresh was performed</returns> public async Task <bool> PopulateNetworkCache(TwitNetworkCache requestCache, int requestDays, int requestLimit, CancellationToken cancellationToken) { TimeSpan updateInterval = (DateTime.Now - requestCache.LastUpdated); if (requestDays > requestCache.RequestDays) { _logger.Info("TWiT network cache does not contain enough requested days"); } else if (updateInterval.TotalHours < 1) { _logger.Info("TWiT network cache is valid and does not require updating yet"); return(false); } else { _logger.Info("TWiT network cache is old and requires an update"); } long requestDaysAgoAsEpoch = GetEpochDate(requestDays); var apiUrl = String.Format("https://twit.tv/api/v1.0/episodes?filter[airingDate][value]={0}&filter[airingDate][operator]={1}", requestDaysAgoAsEpoch, ">="); int callCount = 0; while (true) { if (cancellationToken.IsCancellationRequested) { _logger.Info("Stopping API requests due to cancellation request"); return(false); } // Prevent requesting nothing if (string.IsNullOrEmpty(apiUrl)) { _logger.Debug("Empty apiUrl, halting requests."); return(true); } // Issue the API request and serialize the result for usage var responseStream = await TwitNetworkApiRequest(apiUrl).ConfigureAwait(false); _logger.Debug("Got responseStream [{0}]", apiUrl); var listAllEpisodes = _jsonSerializer.DeserializeFromStream <ListEpisodesResponse>(responseStream); _logger.Debug("Deserialized the responseStream, processing Network Update"); try { // Process the network cache update if (ProcessNetworkCache(requestCache, listAllEpisodes)) { _logger.Debug("Successfully updated TWiT Network cache with this call"); } else { _logger.Debug("Unable to update TWiT Network cache with this call"); } // See if we we have reached the end of the needed API calls if (listAllEpisodes._links.next != null) { listAllEpisodes._links.next.TryGetValue("href", out apiUrl); _logger.Debug("Next href is {0}", apiUrl); } else { _logger.Info("TWiT network cache update is complete"); requestCache.MarkCacheComplete(requestDays); return(true); } } catch (Exception ex) { _logger.Debug("Error when processing the network update: {0}", ex.Message); return(false); } // Iterate the counter, then if the next call will exceed the limit, wait a minute before the next call callCount++; if ((callCount % requestLimit) == 0) { _logger.Debug("Waiting for the next request to be sent due to request limit"); for (int iter = 0; iter < 60; iter++) { if (cancellationToken.IsCancellationRequested) { iter = 60; } else { Thread.Sleep(1000); } } } } }