예제 #1
0
        public void SubscriptionWithExistingCursorGetsAllMessagesAfterMessageBusRestart()
        {
            var sp = ServiceProviderHelper.CreateServiceProvider();

            using (var bus = (MessageBus)sp.GetRequiredService <IMessageBus>())
            {
                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();
                    }
                }
            }
        }
예제 #2
0
        public void GarbageCollectingTopicsAfterGettingTopicsNoops()
        {
            var sp = ServiceProviderHelper.CreateServiceProvider(services =>
            {
                services.ConfigureSignalR(options =>
                {
                    options.Transports.KeepAlive = null;
                });
            });

            using (var bus = (MessageBus)sp.GetRequiredService <IMessageBus>())
            {
                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();
                    }
                }
            }
        }
예제 #3
0
        public void GarbageCollectingTopicsBeforeSubscribingTopicSetsStateToHasSubscription()
        {
            var sp = ServiceProviderHelper.CreateServiceProvider(services =>
            {
                services.SetupOptions <SignalROptions>(options =>
                {
                    options.Transports.DisconnectTimeout = TimeSpan.FromSeconds(6);
                    options.Transports.KeepAlive         = null;
                });
            });

            using (var bus = (MessageBus)sp.GetService <IMessageBus>())
            {
                bus.BeforeTopicMarked = (key, t) =>
                {
                    bus.GarbageCollectTopics();
                };

                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);
            }
        }
예제 #4
0
        public void SubscribingTopicAfterNoSubscriptionsStateSetsStateToHasSubscription()
        {
            var sp = ServiceProviderHelper.CreateServiceProvider(services =>
            {
                services.SetupOptions <SignalROptions>(options =>
                {
                    options.Transports.DisconnectTimeout = TimeSpan.FromSeconds(6);
                });
            });

            using (var bus = (MessageBus)sp.GetService <IMessageBus>())
            {
                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);
            }
        }
예제 #5
0
        public void SubscriptionWithMultipleExistingCursors()
        {
            var sp = ServiceProviderHelper.CreateServiceProvider(services =>
            {
                var passThroughMinfier = new PassThroughStringMinifier();
                services.AddInstance <IStringMinifier>(passThroughMinfier);
            });

            using (var bus = (MessageBus)sp.GetService <IMessageBus>())
            {
                Func <ISubscriber> subscriberFactory = () => 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;

                string prefix = DefaultSubscription._defaultCursorPrefix;

                // Pretend like we had an initial subscription
                bus.Subscribe(subscriberFactory(), null, (result, state) => TaskAsyncHelper.True, 10, null)
                .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(subscriberFactory(), prefix + "key,00000001|key2,00000000", (result, state) =>
                    {
                        foreach (var m in result.GetMessages())
                        {
                            int n = Int32.Parse(m.GetString());
                            if (m.Key == "key")
                            {
                                Assert.True(cdKey.Mark(n));
                            }
                            else
                            {
                                Assert.True(cdKey2.Mark(n));
                            }
                        }

                        return(TaskAsyncHelper.True);
                    }, 10, null);

                    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();
                    }
                }
            }
        }
예제 #6
0
        public void MultipleSubscribeTopicCallsToDeadTopicWork()
        {
            var sp = ServiceProviderHelper.CreateServiceProvider(services =>
            {
                services.SetupOptions <SignalROptions>(options =>
                {
                    options.Transports.DisconnectTimeout = TimeSpan.FromSeconds(6);
                    options.Transports.KeepAlive         = null;
                });
            });

            var ta = new TypeActivator();

            Topic topic;

            using (var bus = ta.CreateInstance <TestMessageBus>(sp))
            {
                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 SubscriptionDoesNotGetNewMessagesWhenTopicStoreOverrunByOtherStream()
        {
            var sp = ServiceProviderHelper.CreateServiceProvider(services =>
            {
                services.SetupOptions <SignalROptions>(options =>
                {
                    options.MessageBus.MessageBufferSize = 10;
                });
            });

            var ta = new TypeActivator();

            using (var bus = ta.CreateInstance <TestScaleoutBus>(sp, 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, "s-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();
                    }
                }
            }
        }