public static void HandleSubscribe(Message message, TextWriter log) { string feedUrl = message.Body.FeedUrl; string imageUri = message.Body.ImageUri; string hash = Convert.ToBase64String(message.Hash.Code); Guid userGuid = message.ObjectId; using (var context = new CommuterDbContext()) { Podcast podcast = context.Podcasts .FirstOrDefault(p => p.FeedUrl == feedUrl); if (podcast == null) { podcast = context.Podcasts.Add(new Podcast { FeedUrl = feedUrl, ImageUri = imageUri }); log.WriteLine($"Adding new podcast {feedUrl}."); } else { log.WriteLine($"Adding subscription for existing podcast {feedUrl}."); } context.Subscriptions.Add(new Subscription { Podcast = podcast, UserGuid = userGuid, Hash = hash }); context.SaveChanges(); } }
public static async Task CheckFeeds(TextWriter log, HttpMessagePump pump) { var yesterday = DateTime.UtcNow.AddDays(-1.0); var halfHourAgo = DateTime.UtcNow.AddHours(-0.5); using (var context = new CommuterDbContext()) { var podcastsToCheck = context.Podcasts .Include("Episodes") .Where(p => context.Subscriptions.Any( s => s.Podcast == p)) .Where(p => p.LastUpdateDateTime == null || p.LastUpdateDateTime < yesterday) .Where(p => p.LastAttemptDateTime == null || p.LastAttemptDateTime < halfHourAgo) .ToImmutableList(); var messages = await Task.WhenAll(podcastsToCheck .Select(p => CheckFeed(p, log))); pump.SendAllMessages(messages .SelectMany(m => m) .ToImmutableList()); await pump.JoinAsync(); if (pump.Exception != null) throw pump.Exception; context.ValidateAndSaveChanges(); } }
public static void HandleUnsubscribe(Message message, TextWriter log) { var hashes = message.GetPredecessors("Subscription") .Select(p => Convert.ToBase64String(p.Code)) .ToList(); using (var context = new CommuterDbContext()) { var predecessors = context.Subscriptions .Where(s => hashes.Contains(s.Hash)) .ToList(); context.Subscriptions.RemoveRange(predecessors); log.WriteLine($"Removing {predecessors.Count} podcast subscriptions"); context.SaveChanges(); } }
public static async Task CheckQueues(TextWriter log, HttpMessagePump pump) { using (var context = new CommuterDbContext()) { await context.Database.ExecuteSqlCommandAsync(@" update Subscription set StartAtEpisodeId = last.EpisodeId from Subscription join ( select s.SubscriptionId, max(e.EpisodeId) EpisodeId from Subscription s join Episode e on e.PodcastId = s.PodcastId where s.StartAtEpisodeId = 0 group by s.SubscriptionId ) last on Subscription.SubscriptionId = last.SubscriptionId "); var episodesToQueue = ( from s in context.Subscriptions where s.StartAtEpisodeId > 0 from e in s.Podcast.Episodes where e.EpisodeId >= s.StartAtEpisodeId where !( from q in s.Queues where q.Episode == e select q ).Any() select new { Subscription = s, Episode = e }) .ToImmutableList(); var distinctEpisodes = episodesToQueue .Select(e => e.Episode) .Distinct() .Count(); var distinctSubscriptions = episodesToQueue .Select(e => e.Subscription) .Distinct() .Count(); log.WriteLine($"Found {distinctEpisodes} new episodes to queue for {distinctSubscriptions} subscriptions."); pump.SendAllMessages(episodesToQueue.Select(e => QueueMessage(e.Subscription, e.Episode)) .ToImmutableList()); await pump.JoinAsync(); if (pump.Exception != null) throw pump.Exception; log.WriteLine($"Sent {episodesToQueue.Count} messages."); foreach (var e in episodesToQueue) { e.Subscription.Queues.Add(new Queue { Episode = e.Episode }); } context.ValidateAndSaveChanges(); log.WriteLine($"Saved {episodesToQueue.Count} records."); } }