/// <summary>Gets ActiveSubscription from a specific Subscription List by persistance.</summary> private ActiveSubscription GetActiveSubscription(SubscriptionPersistence _persistence, string _messageHeader, SubscriberFunction _messageFunction) { ActiveSubscription result = null; switch (_persistence) { case SubscriptionPersistence.Endless: { result = GetEndlessSubscription(_messageHeader, _messageFunction); break; } case SubscriptionPersistence.SingleUse: { result = GetSingleSubscription(_messageHeader, _messageFunction); break; } case SubscriptionPersistence.SoloFrame: { result = GetSoloSubscription(_messageHeader, _messageFunction); break; } default: { break; } } return(result); }
/// <summary>Removes relevant ActiveSubscription and triggers remove functions.</summary> private void ClearRemovedSubscriptions(MPac_SubscriberListRemoved _package) { //Checks whether MessageHeader's prefix is of interest string prefix = MessageHelper.GetPrefix(_package.MessageHeader); if (m_prefixesOfInterest.ContainsKey(prefix)) { //Checks whether Interest matches existing ActiveSubscription foreach (Interest interest in m_prefixesOfInterest[prefix]) { ActiveSubscription subscription = GetActiveSubscription(interest.m_persistence, _package.MessageHeader, interest.m_messageFunction); //If it exists, clears ActiveSubscription if (subscription != null) { if (subscription.m_dynamicMessageHeader == _package.MessageHeader) { interest.m_removeFunction(_package); ClearActiveSubscription(interest, _package.MessageHeader); } } } } //Checks whether Messageheader matches existing ActiveSubscription if (m_dynamicMessagesOfInterest.ContainsKey(_package.MessageHeader)) { //If it exists, clears ActiveSubscription foreach (Interest interest in m_dynamicMessagesOfInterest[_package.MessageHeader]) { interest.m_removeFunction(_package); ClearActiveSubscription(interest, _package.MessageHeader); } } }
/// <summary> /// This method "rolls forward" subscriptions, which means if the user unsubscribed we /// make sure the subscription is billed until the end of their billing period by extending /// the subscription length here. /// </summary> public IReadOnlyList <MergedSnapshot> Execute( DateTime endTimeExclusive, IReadOnlyList <MergedSnapshot> inputSnapshots) { var snapshots = inputSnapshots.ToList(); var activeSubscriptions = new Dictionary <ChannelId, ActiveSubscription>(); for (int i = 0; i < snapshots.Count; i++) { var snapshot = snapshots[i]; foreach (var subscription in snapshot.SubscriberChannels.SubscribedChannels) { var billingWeekEndDateExclusive = BillingWeekUtilities.CalculateBillingWeekEndDateExclusive( subscription.SubscriptionStartDate, snapshot.Timestamp); ActiveSubscription activeSubscription; if (activeSubscriptions.TryGetValue(subscription.ChannelId, out activeSubscription)) { // The following condition is a relaxation to allow people to briefly re-subscribe without // trigging a whole new billing week, and therefore to reduce anticipated complaints. // If they restarted their subscription before the minumum end date of their // previous subscription, then we do not reset the minimum end date yet. // However if they exceed that billing week then the new subscription's billing week will be used. if (snapshot.Timestamp < activeSubscription.BillingWeekEndDateExclusive) { billingWeekEndDateExclusive = activeSubscription.BillingWeekEndDateExclusive; } activeSubscription = new ActiveSubscription(billingWeekEndDateExclusive, subscription); activeSubscriptions[subscription.ChannelId] = activeSubscription; } else { activeSubscription = new ActiveSubscription(billingWeekEndDateExclusive, subscription); activeSubscriptions.Add(subscription.ChannelId, activeSubscription); } } // Copy the list so we can modify activeSubscriptions within the loop. foreach (var activeSubscription in activeSubscriptions.Values.ToList()) { var activeChannelId = activeSubscription.Subscription.ChannelId; if (snapshot.SubscriberChannels.SubscribedChannels.All(v => !v.ChannelId.Equals(activeChannelId))) { // The subscriber has unsubscribed from this channel. var billingWeekFinalSnapshotTime = this.GetBillingWeekFinalSnapshotTime(activeSubscription.BillingWeekEndDateExclusive); var subscriptionDuration = snapshot.Timestamp - activeSubscription.Subscription.SubscriptionStartDate; if (subscriptionDuration.TotalDays > DaysInWeek) { // We have exceeded the minimum subscripion period, so there is nothing to adjust. activeSubscriptions.Remove(activeSubscription.Subscription.ChannelId); } else if (snapshot.Timestamp == billingWeekFinalSnapshotTime) { // We are at the end of the billing week, so there is nothing to adjust. activeSubscriptions.Remove(activeSubscription.Subscription.ChannelId); } else if (snapshot.Timestamp < billingWeekFinalSnapshotTime) { if (snapshot.CreatorChannels.CreatorChannels.All(v => !v.ChannelId.Equals(activeChannelId))) { // We are within the billing week, but the channel is no longer published. // So we stop billing at this point. activeSubscriptions.Remove(activeSubscription.Subscription.ChannelId); } else { // We are still within their billing week and the creator still publishes the channel. // We must extend their subscription to this snapshot. var newSnapshot = new MergedSnapshot( snapshot.Timestamp, snapshot.CreatorChannels, snapshot.CreatorFreeAccessUsers, new SubscriberChannelsSnapshot( snapshot.SubscriberChannels.Timestamp, snapshot.SubscriberChannels.SubscriberId, snapshot.SubscriberChannels.SubscribedChannels.Concat(new[] { activeSubscription.Subscription }).ToList()), snapshot.Subscriber, snapshot.CalculatedAccountBalance); snapshots[i] = newSnapshot; if ((i == snapshots.Count - 1 && activeSubscription.BillingWeekEndDateExclusive < endTimeExclusive) || (i < snapshots.Count - 1 && snapshots[i + 1].Timestamp > billingWeekFinalSnapshotTime)) { // Either this is the last snapshot and the billing week ends before the end date of // our search range, or the next snapshot will be in the next billing week. // Either way, we need to insert a snapshot to end the biling at the correct time. var endSnapshot = new MergedSnapshot( billingWeekFinalSnapshotTime, snapshot.CreatorChannels, snapshot.CreatorFreeAccessUsers, snapshot.SubscriberChannels, snapshot.Subscriber, snapshot.CalculatedAccountBalance); snapshots.Insert(i + 1, endSnapshot); } snapshot = snapshots[i]; } } } } } return(snapshots); }
public void Dispose() { ActiveSubscription.Dispose(); }