예제 #1
0
        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();
            }
        }
예제 #2
0
        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();
            }
        }
예제 #3
0
        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();
            }
        }
예제 #4
0
        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.");
            }
        }