상속: ISubscriber
예제 #1
0
        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();
            }
        }
예제 #2
0
        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();
                    }
                }
            }
        }
예제 #5
0
        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);
            }
        }
예제 #6
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();
                    }
                }
            }
        }
예제 #7
0
        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();
                    }
                }
            }
        }
예제 #8
0
        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();
                    }
                }
            }
        }
예제 #9
0
        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();
                    }
                }
            }
        }
예제 #10
0
        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();
                    }
                }
            }
        }
예제 #11
0
        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);
            }
        }
예제 #12
0
        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();
                    }
                }
            }
        }
예제 #14
0
        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();
                    }
                }
            }
        }
예제 #15
0
        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();
                    }
                }
            }
        }
예제 #16
0
        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);
            }
        }
예제 #17
0
        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);
            }
        }
예제 #18
0
        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);
            }
        }
예제 #19
0
        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);
            }
        }
예제 #20
0
        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);
            }
        }
예제 #21
0
        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();
                    }
                }
            }
        }
예제 #24
0
        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();
                    }
                }
            }
        }
예제 #25
0
        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();
                    }
                }
            }
        }