public void SubscriptionWithCancelledTaskCanBeDisposed() { var dr = new DefaultDependencyResolver(); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); var wh = new ManualResetEventSlim(); IDisposable subscription = bus.Subscribe(subscriber, null, async (result, state) => { if (result.Terminal) { return false; } await Task.Delay(50); var tcs = new TaskCompletionSource<bool>(); tcs.SetCanceled(); wh.Set(); return await tcs.Task; }, 10, null); bus.Publish("me", "key", "hello"); wh.Wait(); subscription.Dispose(); } }
public void SubscriptionDoesNotGetNewMessagesWhenTopicStoreOverrunByOtherStream() { var dr = new DefaultDependencyResolver(); dr.Resolve<IConfigurationManager>().DefaultMessageBufferSize = 10; using (var bus = new TestScaleoutBus(dr, streams: 2)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; // The min fragment size is 8 and min fragments is 5 var expectedValues = Enumerable.Range(171, 8); var cd = new OrderedCountDownRange<int>(expectedValues); // This will overwrite the buffer ending up with (40 - 79) for stream 2 for (int i = 0; i < 80; i++) { bus.Publish(0, (ulong)i, new[] { new Message("test", "key", i.ToString()) }); } // This will overwrite the buffer with (140 - 179) for stream 1 for (int i = 100; i < 180; i++) { bus.Publish(1, (ulong)i, new[] { new Message("test", "key", i.ToString()) }); } try { subscription = bus.Subscribe(subscriber, "0,27|1,AA", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); cd.Expect(n); } return TaskAsyncHelper.True; }, 100, null); Assert.True(cd.Wait(TimeSpan.FromSeconds(10))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void NewSubscriptionGetsAllMessages() { var dr = new DefaultDependencyResolver(); using (var bus = new TestScaleoutBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); var wh = new ManualResetEventSlim(initialState: false); IDisposable subscription = null; try { var firstMessages = new[] { new Message("test1", "key", "1"), new Message("test2", "key", "2") }; bus.Publish(0, 0, firstMessages); subscription = bus.Subscribe(subscriber, null, (result, state) => { if (!result.Terminal) { var ms = result.GetMessages().ToList(); Assert.Equal(2, ms.Count); Assert.Equal("key", ms[0].Key); Assert.Equal("x", ms[0].GetString()); Assert.Equal("key", ms[1].Key); Assert.Equal("y", ms[1].GetString()); wh.Set(); return TaskAsyncHelper.True; } return TaskAsyncHelper.False; }, 10, null); var messages = new[] { new Message("test1", "key", "x"), new Message("test1", "key", "y") }; bus.Publish(0, 1, messages); Assert.True(wh.Wait(TimeSpan.FromSeconds(10))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionWithExistingCursor() { var dr = new DefaultDependencyResolver(); using (var bus = new TestScaleoutBus(dr, streams: 2)) { var subscriber = new TestSubscriber(new[] { "key" }); var cd = new CountDownRange<int>(Enumerable.Range(2, 4)); IDisposable subscription = null; bus.Publish(0, 0, new[] { new Message("test", "key", "1"), new Message("test", "key", "50") }); bus.Publish(1, 0, new[] { new Message("test1", "key", "51") }); bus.Publish(1, 2, new[]{ new Message("test2", "key", "2"), new Message("test3", "key", "3"), new Message("test2", "key", "4"), }); try { subscription = bus.Subscribe(subscriber, "s-0,00000000|1,00000000", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); Assert.True(cd.Mark(n)); } return TaskAsyncHelper.True; }, 10, null); bus.Publish(0, 2, new[] { new Message("test", "key", "5") }); Assert.True(cd.Wait(TimeSpan.FromSeconds(10))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void DisposingBusShutsWorkersDown() { var dr = new DefaultDependencyResolver(); var bus = new MessageBus(dr); var subscriber = new TestSubscriber(new[] { "key" }); var wh = new ManualResetEventSlim(initialState: false); IDisposable subscription = null; try { subscription = bus.Subscribe(subscriber, null, result => { if (!result.Terminal) { var m = result.GetMessages().Single(); Assert.Equal("key", m.Key); Assert.Equal("value", m.Value); wh.Set(); return TaskAsyncHelper.True; } return TaskAsyncHelper.False; }, 10); bus.Publish("test", "key", "value").Wait(); Assert.True(wh.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } Assert.Equal(bus.AllocatedWorkers, 1); bus.Dispose(); Assert.Equal(bus.AllocatedWorkers, 0); } }
public void NewSubscriptionGetsAllMessages() { var dr = new DefaultDependencyResolver(); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); var wh = new ManualResetEventSlim(initialState: false); IDisposable subscription = null; try { bus.Publish("test", "key", "1").Wait(); subscription = bus.Subscribe(subscriber, null, (result, state) => { if (!result.Terminal) { var m = result.GetMessages().Single(); Assert.Equal("key", m.Key); Assert.Equal("value", m.GetString()); wh.Set(); return TaskAsyncHelper.True; } return TaskAsyncHelper.False; }, 10, null); bus.Publish("test", "key", "value").Wait(); Assert.True(wh.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void AddingEventAndSendingMessages() { var dr = new DefaultDependencyResolver(); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "a" }); int max = 100; var cd = new CountDownRange<int>(Enumerable.Range(0, max)); int prev = -1; IDisposable subscription = null; try { subscription = bus.Subscribe(subscriber, null, result => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.Value); Assert.True(prev < n, "out of order"); prev = n; Assert.True(cd.Mark(n)); } return TaskAsyncHelper.True; }, 10); for (int i = 0; i < max; i++) { subscriber.AddEvent("b"); bus.Publish("test", "b", i.ToString()).Wait(); } Assert.True(cd.Wait(TimeSpan.FromSeconds(10))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionPublishingAfter() { var dr = new DefaultDependencyResolver(); using (var bus = new TestScaleoutBus(dr, topicCount: 5)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; var wh = new ManualResetEventSlim(); // test, test2 = 1 // test1, test3 = 0 try { subscription = bus.Subscribe(subscriber, null, result => { if (!result.Terminal) { var messages = result.GetMessages().ToList(); Assert.Equal(1, messages.Count); Assert.Equal("connected", messages[0].Value); wh.Set(); } return TaskAsyncHelper.True; }, 10); bus.SendMany(new[] { new Message("test", "key", "connected") }); Assert.True(wh.Wait(TimeSpan.FromSeconds(10))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public async Task SubscriptionWithExistingCursorGetsAllMessagesAfterMessageBusRestart() { var dr = new DefaultDependencyResolver(); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); var tcs = new TaskCompletionSource <object>(); IDisposable subscription = null; try { subscription = bus.Subscribe(subscriber, "d-key,00000001", (result, state) => { foreach (var m in result.GetMessages()) { Assert.Equal("key", m.Key); Assert.Equal("value", m.GetString()); tcs.TrySetResult(null); } return(TaskAsyncHelper.True); }, 10, null); _ = bus.Publish("test", "key", "value"); await tcs.Task.OrTimeout(); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionWithExistingCursorGetsAllMessagesAfterMessageBusRestart() { var dr = new DefaultDependencyResolver(); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); var wh = new ManualResetEvent(false); IDisposable subscription = null; try { subscription = bus.Subscribe(subscriber, "key,00000001", result => { foreach (var m in result.GetMessages()) { Assert.Equal("key", m.Key); Assert.Equal("value", m.Value); wh.Set(); } return(TaskAsyncHelper.True); }, 10); bus.Publish("test", "key", "value"); Assert.True(wh.WaitOne(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void GettingTopicAfterNoSubscriptionsWhenGCStateSetsStateToHasSubscriptions() { var dr = new DefaultDependencyResolver(); using (var bus = new TestMessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); int retries = 0; // Make sure the topic is in the no subs state bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null) .Dispose(); bus.BeforeTopicMarked = (key, t) => { if (retries == 0) { bus.GarbageCollectTopics(); } retries++; }; bus.AfterTopicMarked = (key, t, state) => { if (retries == 1) { Assert.Equal(TopicState.Dead, state); } }; Topic topic = bus.GetTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); Assert.Equal(2, retries); } }
public void SubscriptionWithMultipleExistingCursors() { var dr = new DefaultDependencyResolver(); var bus = new MessageBus(dr); var subscriber = new TestSubscriber(new[] { "key", "key2" }); var cdKey = new CountDownRange<int>(Enumerable.Range(2, 4)); var cdKey2 = new CountDownRange<int>(new[] { 1, 2, 10 }); IDisposable subscription = null; bus.Publish("test", "key", "1").Wait(); bus.Publish("test", "key", "2").Wait(); bus.Publish("test", "key", "3").Wait(); bus.Publish("test", "key", "4").Wait(); bus.Publish("test", "key2", "1").Wait(); bus.Publish("test", "key2", "2").Wait(); try { subscription = bus.Subscribe(subscriber, "key,00000001|key2,00000000", result => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.Value); if (m.Key == "key") { Assert.True(cdKey.Mark(n)); } else { Assert.True(cdKey2.Mark(n)); } } return TaskAsyncHelper.True; }, 10); bus.Publish("test", "key", "5"); bus.Publish("test", "key2", "10"); Assert.True(cdKey.Wait(TimeSpan.FromSeconds(5))); Assert.True(cdKey2.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } }
public void SubscriptionGetsNewMessagesWhenTopicStoreOverrun() { var dr = new DefaultDependencyResolver(); dr.Resolve<IConfigurationManager>().DefaultMessageBufferSize = 10; using (var bus = new TestScaleoutBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; // 16-49 is the valid range var cd = new OrderedCountDownRange<int>(Enumerable.Range(16, 33)); var results = new List<bool>(); for (int i = 0; i < 50; i++) { bus.Publish(0, (ulong)i, new[] { new Message("test", "key", i.ToString()) }); } try { subscription = bus.Subscribe(subscriber, "s-0,1", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); cd.Expect(n); } return TaskAsyncHelper.True; }, 10, null); Assert.True(cd.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionWithExistingCursorGetsAllMessagesAfterMessageBusRestart() { var dr = new DefaultDependencyResolver(); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); var wh = new ManualResetEvent(false); IDisposable subscription = null; try { subscription = bus.Subscribe(subscriber, "d-key,00000001", (result, state) => { foreach (var m in result.GetMessages()) { Assert.Equal("key", m.Key); Assert.Equal("value", m.GetString()); wh.Set(); } return TaskAsyncHelper.True; }, 10, null); bus.Publish("test", "key", "value"); Assert.True(wh.WaitOne(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionWithExistingCursor() { var dr = new DefaultDependencyResolver(); using (var bus = new TestScaleoutBus(dr, topicCount: 2)) { var subscriber = new TestSubscriber(new[] { "key" }); var cd = new CountDownRange<int>(Enumerable.Range(2, 4)); IDisposable subscription = null; // test, test2 = 1 // test1, test3 = 0 // // Cursor 1, 1 bus.SendMany(new[] { new Message("test", "key", "1"), new Message("test", "key", "50") }); // Cursor 0,1|1,1 bus.SendMany(new[] { new Message("test1", "key", "51") }); bus.SendMany(new[]{ new Message("test2", "key", "2"), new Message("test3", "key", "3"), new Message("test2", "key", "4"), }); try { subscription = bus.Subscribe(subscriber, "0,00000001|1,00000001", result => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.Value); Assert.True(cd.Mark(n)); } return TaskAsyncHelper.True; }, 10); bus.SendMany(new[] { new Message("test", "key", "5") }); Assert.True(cd.Wait(TimeSpan.FromSeconds(10))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void MultipleSubscribeTopicCallsToDeadTopicWork() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve <IConfigurationManager>(); Topic topic; configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); configuration.KeepAlive = null; using (var bus = new TestMessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); int count = 0; // Make sure the topic is in the no subs state bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null) .Dispose(); bus.BeforeTopicCreated = (key) => { bus.Topics.TryGetValue(key, out topic); if (count == 1) { // Should have been removed by our double garbage collect in BeforeTopicMarked Assert.Null(topic); } if (count == 3) { // Ensure that we have a topic now created from the original thread Assert.NotNull(topic); } }; bus.BeforeTopicMarked = (key, t) => { count++; if (count == 1) { bus.GarbageCollectTopics(); bus.GarbageCollectTopics(); // We garbage collect twice to mark the current topic as dead (it will remove it from the topics list) Assert.Equal(t.State, TopicState.Dead); bus.SubscribeTopic("key"); // Topic should still be dead Assert.Equal(t.State, TopicState.Dead); Assert.Equal(count, 2); // Increment up to 3 so we don't execute same code path in after marked count++; } if (count == 2) { // We've just re-created the topic from the second bus.SubscribeTopic so we should have 0 subscriptions Assert.Equal(t.State, TopicState.NoSubscriptions); } if (count == 4) { // Ensure that we pulled the already created subscription (therefore it has subscriptions) Assert.Equal(t.State, TopicState.HasSubscriptions); } }; bus.AfterTopicMarked = (key, t, state) => { if (count == 2) { // After re-creating the topic from the second bus.SubscribeTopic we should then move the topic state // into the has subscriptions state Assert.Equal(state, TopicState.HasSubscriptions); } if (count == 3) { Assert.Equal(state, TopicState.Dead); } }; bus.SubscribeTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } }
public void MultipleSubscribeTopicCallsToDeadTopicWork() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); Topic topic; configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); configuration.KeepAlive = null; using (var bus = new TestMessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); int count = 0; // Make sure the topic is in the no subs state bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null) .Dispose(); bus.BeforeTopicCreated = (key) => { bus.Topics.TryGetValue(key, out topic); if (count == 1) { // Should have been removed by our double garbage collect in BeforeTopicMarked Assert.Null(topic); } if (count == 3) { // Ensure that we have a topic now created from the original thread Assert.NotNull(topic); } }; bus.BeforeTopicMarked = (key, t) => { count++; if (count == 1) { bus.GarbageCollectTopics(); bus.GarbageCollectTopics(); // We garbage collect twice to mark the current topic as dead (it will remove it from the topics list) Assert.Equal(t.State, TopicState.Dead); bus.SubscribeTopic("key"); // Topic should still be dead Assert.Equal(t.State, TopicState.Dead); Assert.Equal(count, 2); // Increment up to 3 so we don't execute same code path in after marked count++; } if (count == 2) { // We've just re-created the topic from the second bus.SubscribeTopic so we should have 0 subscriptions Assert.Equal(t.State, TopicState.NoSubscriptions); } if (count == 4) { // Ensure that we pulled the already created subscription (therefore it has subscriptions) Assert.Equal(t.State, TopicState.HasSubscriptions); } }; bus.AfterTopicMarked = (key, t, state) => { if (count == 2) { // After re-creating the topic from the second bus.SubscribeTopic we should then move the topic state // into the has subscriptions state Assert.Equal(state, TopicState.HasSubscriptions); } if (count == 3) { Assert.Equal(state, TopicState.Dead); } }; bus.SubscribeTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } }
public void SubscribingTopicAfterNoSubscriptionsStateSetsStateToHasSubscription() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); configuration.DisconnectTimeout = TimeSpan.FromSeconds(6); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); // Make sure the topic is in the no subs state bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null) .Dispose(); Topic topic = bus.SubscribeTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } }
public void SubscribingTopicAfterNoSubscriptionsWhenGCStateSetsStateToHasSubscription() { var dr = new DefaultDependencyResolver(); using (var bus = new TestMessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); int retries = 0; // Make sure the topic is in the no subs state bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null) .Dispose(); bus.BeforeTopicMarked = (key, t) => { if (retries == 0) { // Need to garbage collect twice to force the topic into the dead state bus.GarbageCollectTopics(); Assert.Equal(TopicState.Dying, t.State); } retries++; }; bus.AfterTopicMarked = (key, t, state) => { if (retries == 1) { // Assert that we've revived the topic from dying since we've subscribed to the topic Assert.Equal(TopicState.HasSubscriptions, state); } }; Topic topic = bus.SubscribeTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); Assert.Equal(1, retries); } }
public void GettingTopicAfterNoSubscriptionsWhenGCStateSetsStateToHasSubscriptions() { var dr = new DefaultDependencyResolver(); using (var bus = new TestMessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); int retries = 0; // Make sure the topic is in the no subs state bus.Subscribe(subscriber, null, _ => TaskAsyncHelper.True, 10) .Dispose(); bus.BeforeTopicMarked = (key, t) => { if (retries == 0) { bus.GarbageCollectTopics(); } retries++; }; bus.AfterTopicMarked = (key, t, state) => { if (retries == 1) { Assert.Equal(TopicState.Dead, state); } }; Topic topic = bus.GetTopic("key"); Assert.Equal(1, bus.Topics.Count); Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); Assert.Equal(2, retries); } }
public void GarbageCollectingTopicsAfterGettingTopicsNoops() { var dr = new DefaultDependencyResolver(); var configuration = dr.Resolve<IConfigurationManager>(); configuration.KeepAlive = null; using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; bus.AfterTopicMarkedSuccessfully = (key, topic) => { bus.GarbageCollectTopics(); }; try { subscription = bus.Subscribe(subscriber, null, (result, state) => TaskAsyncHelper.True, 10, null); Assert.Equal(1, bus.Topics.Count); Topic topic; Assert.True(bus.Topics.TryGetValue("key", out topic)); Assert.Equal(TopicState.HasSubscriptions, topic.State); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionWithDefaultCursorGetsOnlyNewMessages() { var dr = new DefaultDependencyResolver(); using (var bus = new TestScaleoutBus(dr, streams: 1)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; var tcs = new TaskCompletionSource<MessageResult>(); bus.Publish(0, 1ul, new[] { new Message("test", "key", "badvalue") }); try { subscription = bus.Subscribe(subscriber, "d-0,0", (result, state) => { tcs.TrySetResult(result); return TaskAsyncHelper.True; }, 100, null); bus.Publish(0, 2ul, new[] { new Message("test", "key", "value") }); Assert.True(tcs.Task.Wait(TimeSpan.FromSeconds(5))); foreach (var m in tcs.Task.Result.GetMessages()) { Assert.Equal("key", m.Key); Assert.Equal("value", m.GetString()); } } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionGetsCorrectCursorsIfLessKeysThanStreams() { var dr = new DefaultDependencyResolver(); using (var bus = new TestScaleoutBus(dr, streams: 2)) { var subscriber = new TestSubscriber(new[] { "key" }); IDisposable subscription = null; var cd = new OrderedCountDownRange<int>(new[] { 101, 11 }); bus.Publish(0, 10ul, new[] { new Message("test", "key", "100") }); bus.Publish(1, 10ul, new[] { new Message("test", "key", "10") }); try { subscription = bus.Subscribe(subscriber, "s-0,0", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); cd.Expect(n); } return TaskAsyncHelper.True; }, 100, null); bus.Publish(0, 11ul, new[] { new Message("test", "key", "101") }, new DateTime(TimeSpan.TicksPerDay * 1)); bus.Publish(1, 11ul, new[] { new Message("test", "key", "11") }, new DateTime(TimeSpan.TicksPerDay * 2)); Assert.True(cd.Wait(TimeSpan.FromSeconds(10))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionWithMultipleExistingCursors() { var dr = new DefaultDependencyResolver(); var passThroughMinfier = new PassThroughStringMinifier(); dr.Register(typeof(IStringMinifier), () => passThroughMinfier); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key", "key2" }); var cdKey = new CountDownRange<int>(Enumerable.Range(2, 4)); var cdKey2 = new CountDownRange<int>(new[] { 1, 2, 10 }); IDisposable subscription = null; // Pretend like we had an initial subscription bus.Subscribe(subscriber, null, result => TaskAsyncHelper.True, 10) .Dispose(); // This simulates a reconnect bus.Publish("test", "key", "1").Wait(); bus.Publish("test", "key", "2").Wait(); bus.Publish("test", "key", "3").Wait(); bus.Publish("test", "key", "4").Wait(); bus.Publish("test", "key2", "1").Wait(); bus.Publish("test", "key2", "2").Wait(); try { subscription = bus.Subscribe(subscriber, "key,00000001|key2,00000000", result => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.Value); if (m.Key == "key") { Assert.True(cdKey.Mark(n)); } else { Assert.True(cdKey2.Mark(n)); } } return TaskAsyncHelper.True; }, 10); bus.Publish("test", "key", "5"); bus.Publish("test", "key2", "10"); Assert.True(cdKey.Wait(TimeSpan.FromSeconds(5))); Assert.True(cdKey2.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionWithExistingCursor() { var dr = new DefaultDependencyResolver(); var passThroughMinfier = new PassThroughStringMinifier(); dr.Register(typeof(IStringMinifier), () => passThroughMinfier); using (var bus = new MessageBus(dr)) { var subscriber = new TestSubscriber(new[] { "key" }); var cd = new CountDownRange<int>(Enumerable.Range(2, 4)); IDisposable subscription = null; bus.Publish("test", "key", "1").Wait(); bus.Publish("test", "key", "2").Wait(); bus.Publish("test", "key", "3").Wait(); bus.Publish("test", "key", "4").Wait(); try { subscription = bus.Subscribe(subscriber, "key,00000001", result => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.Value); Assert.True(cd.Mark(n)); } return TaskAsyncHelper.True; }, 10); bus.Publish("test", "key", "5"); Assert.True(cd.Wait(TimeSpan.FromSeconds(5))); } finally { if (subscription != null) { subscription.Dispose(); } } } }
public void SubscriptionPullFromMultipleStreamsInFairOrder() { var dr = new DefaultDependencyResolver(); using (var bus = new TestScaleoutBus(dr, streams: 3)) { var subscriber = new TestSubscriber(new[] { "key" }); var cd = new OrderedCountDownRange<int>(new[] { 1, 2, 4, 3 }); IDisposable subscription = null; bus.Publish(0, 1, new[] { new Message("test", "key", "3"), new Message("test", "key2", "5"), }, new DateTime(TimeSpan.TicksPerDay * 5, DateTimeKind.Local)); bus.Publish(1, 1, new[] { new Message("test", "key", "1"), new Message("test", "key2", "foo") }, new DateTime(TimeSpan.TicksPerDay * 1, DateTimeKind.Local)); bus.Publish(2, 1, new[] { new Message("test", "key", "2"), new Message("test", "key", "4") }, new DateTime(TimeSpan.TicksPerDay * 2, DateTimeKind.Local)); try { subscription = bus.Subscribe(subscriber, "s-0,0|1,0|2,0", (result, state) => { foreach (var m in result.GetMessages()) { int n = Int32.Parse(m.GetString()); Assert.True(cd.Expect(n)); } return TaskAsyncHelper.True; }, 10, null); Assert.True(cd.Wait(TimeSpan.FromSeconds(10))); } finally { if (subscription != null) { subscription.Dispose(); } } } }