public void Expiration() { // Arrange var topicName = "HousekeepingTests.Expiration"; var subName = topicName + "_Sub1"; var topic = _publisher.AddOrUpdateTopic(new Topic { Name = topicName }); var sub1 = _consumer.AddOrUpdateSubscription(new Subscription { Name = subName, TopicSubscriptions = new List <TopicSubscription> { new TopicSubscription { TopicId = topic.Id.Value, Enabled = true } }, }); var utcNow = DateTime.UtcNow; _publisher.Publish(topicName, eventName: topicName + "1", expirationDateUtc: utcNow.AddSeconds(5), payload: "1"); _publisher.Publish(topicName, eventName: topicName + "2", expirationDateUtc: utcNow.AddSeconds(5), payload: "2"); _publisher.Publish(topicName, eventName: topicName + "3", expirationDateUtc: utcNow.AddMinutes(15), payload: "3"); var visibilityTimeout = 1; // Must expire asap var ce1 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault(); var ce2 = _consumer.ConsumeNext(subName, visibilityTimeout: 10).SingleOrDefault(); // Still invisible after expiration var ce3 = _consumer.ConsumeNext(subName, visibilityTimeout: visibilityTimeout).SingleOrDefault(); Assert.Equal("1", ce1.Payload); // Not yet expired Assert.Equal("2", ce2.Payload); Assert.Equal("3", ce3.Payload); Thread.Sleep(TimeSpan.FromSeconds(5 + 1)); _consumer.PerformHouseKeepingTasks(); // Check that only 1 se in table var eventNames = _fixture.GetEventNamesForFailedEvents(sub1.Id.Value); Assert.Equal(1, eventNames.Count); Assert.Equal(topicName + "1", eventNames.First()); // 2 has expired, but is still invisible, so may still be processed }
public void SubscriptionStatistics() { // Arrange var topicName = "SubStats"; var subName = topicName + "_Sub1"; var topic = _publisher.AddOrUpdateTopic(new Topic { Name = topicName }); var sub1 = _consumer.AddOrUpdateSubscription(new Subscription { Name = subName, Ordered = true, MaxDeliveries = 1, TopicSubscriptions = new List <TopicSubscription> { new TopicSubscription { TopicId = topic.Id.Value, Enabled = true } }, }); var utcNow = DateTime.UtcNow; var funcKey = "A"; // Create situation: failed-other (marked) _publisher.Publish(topicName, eventName: topicName + "0", functionalKey: funcKey); var ce = _consumer.ConsumeNext(sub1.Name).SingleOrDefault(); _consumer.MarkFailed(ce.Id, ce.DeliveryKey, Reason.Other("Some other reason")); // Create situation: expired _publisher.Publish(topicName, eventName: topicName + "1", functionalKey: funcKey, expirationDateUtc: utcNow); Thread.Sleep(TimeSpan.FromSeconds(1)); // Expired for sure // Create situation: maxDeliveriesReached _publisher.Publish(topicName, eventName: topicName + "2", functionalKey: funcKey); ce = _consumer.ConsumeNext(sub1.Name, visibilityTimeout: 1).SingleOrDefault(); Assert.Equal(topicName + "2", ce.EventName); Thread.Sleep(TimeSpan.FromSeconds(1 + 1)); // Becomes visible again, but has reached maxDeliveries // Create situation: overtaken _publisher.Publish(topicName, eventName: topicName + "3", functionalKey: funcKey, publicationDateUtc: utcNow.AddSeconds(2)); ce = _consumer.ConsumeNext(sub1.Name).SingleOrDefault(); Assert.Equal(topicName + "3", ce.EventName); _publisher.Publish(topicName, eventName: topicName + "4", functionalKey: funcKey, publicationDateUtc: utcNow.AddSeconds(-1)); _consumer.MarkConsumed(ce.Id, ce.DeliveryKey); // #4 is now overtaken _publisher.Publish(topicName, eventName: topicName + "5", functionalKey: funcKey); var statsBeforeHouseKeeping = _consumer.GetSubscriptionStatistics(utcNow.AddMinutes(-10), utcNow.AddMinutes(+10)); Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).Open, 4); // 4 open, since housekeeping has not yet moved them (3) to failed Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).Consumed, 1); Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedExpired, 0); Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedMaxDeliveriesReached, 0); Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedOvertaken, 0); Assert.Equal(statsBeforeHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedOther, 1); // Does not need housekeeping to move it _consumer.PerformHouseKeepingTasks(); var statsAfterHouseKeeping = _consumer.GetSubscriptionStatistics(utcNow.AddMinutes(-10), utcNow.AddMinutes(+10)); Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).Open, 1); Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).Consumed, 1); Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedExpired, 1); Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedMaxDeliveriesReached, 1); Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedOvertaken, 1); Assert.Equal(statsAfterHouseKeeping.Single(s => s.Subscription.Id.Value == sub1.Id).FailedOther, 1); }