示例#1
0
        // same as previous but should not deliver the message
        // because the second subscriber has also the same filter
        public async Task Test_DeliverAtLeastOnce_Delayed2()
        {
            var  hub = new MetaPubSub();
            bool timeoutException = false;

            // first subscriber which will not process the message due to its filter
            hub.Subscribe <MyMessage>(OnMyMessageHandler, OnMyMessagePredicate);

            // second subscriber which will subscribe after the message has been published
            var t = Task.Run(async() =>
            {
                await Task.Delay(50);
                hub.Subscribe <MyMessage>(OnMyMessageHandler2, OnMyMessagePredicate);
                await hub.Unsubscribe <MyMessage>(OnMyMessageHandler2);
            });

            var message = new MyMessage {
                LogSeverity = MetaLogErrorSeverity.Info, DeliverAtLeastOnce = true, WaitForSubscriberTimeout = 100
            };

            try
            {
                // the message has a timeout and can wait until the second subscriber come
                await hub.Publish(message);
            }
            catch (TimeoutException)
            {
                timeoutException = true;
            }
            Assert.IsTrue(timeoutException);
            Assert.IsTrue(message.DeliveredCount == 0);

            await hub.Unsubscribe <MyMessage>(OnMyMessageHandler);
        }
示例#2
0
        // subscribed twice but delivered only once
        public async Task Basic()
        {
            var hub = new MetaPubSub();


            await Task.Run(() =>
            {
                for (int i = 0; i < 10_000; i++)
                {
                    var subscriber = new MySubscriber();
                    //await Task.Delay(50);
                    hub.Subscribe <MyMessage>(subscriber.Handler);
                }
            });

            int totalDeliveryCount1 = 0;
            var t1 = Task.Run(async() =>
            {
                for (int i = 0; i < 1000; i++)
                {
                    var subscriber = new MySubscriber();
                    hub.Subscribe <MyEvent>(subscriber.Handler);

                    var message = new MyMessage();
                    await hub.Publish(message);
                    totalDeliveryCount1 += message.DeliveredCount;

                    await hub.Unsubscribe <MyEvent>(subscriber.Handler);
                }
            });

            int totalDeliveryCount2 = 0;
            var t2 = Task.Run(async() =>
            {
                for (int i = 0; i < 1000; i++)
                {
                    var subscriber = new MySubscriber();
                    hub.Subscribe <MyMessage>(subscriber.Handler);

                    var message = new MyMessage();
                    await hub.Publish(message);
                    totalDeliveryCount2 += message.DeliveredCount;

                    await hub.Unsubscribe <MyMessage>(subscriber.Handler);
                }
            });

            await Task.WhenAll(t1, t2);

            Assert.IsTrue(totalDeliveryCount1 > (10_000 * 1000) && totalDeliveryCount1 < (10_000 * 1000 + 1000));
            Assert.IsTrue(totalDeliveryCount2 == 10_000 * 1000 + 1000);
        }
示例#3
0
        // Should deliver if message is filtered at first and DeliverAtLeastOnce = true but Timeout > 0 and
        // after the message has published a new subscriber arrived
        public async Task Test_DeliverAtLeastOnce_Delayed()
        {
            var hub = new MetaPubSub();

            // first subscriber which will not process the message due to its filter
            hub.Subscribe <MyMessage>(OnMyMessageHandler, OnMyMessagePredicate);

            // second subscriber which will subscribe after the message has been published
            // also with filter, will not process the message
            var t = Task.Run(async() =>
            {
                await Task.Delay(50);
                hub.Subscribe <MyMessage>(OnMyMessageHandler2, OnMyMessagePredicate);
            });

            // third subscriber which will subscribe after the message has been published
            var t2 = Task.Run(async() =>
            {
                await Task.Delay(70);
                hub.Subscribe <MyMessage>(OnMyMessageHandler3);
            });

            var message = new MyMessage {
                LogSeverity = MetaLogErrorSeverity.Info, DeliverAtLeastOnce = true, WaitForSubscriberTimeout = 200000
            };
            // the message has a timeout and can wait until the second subscriber come
            await hub.Publish(message);

            Assert.IsTrue(message.DeliveredCount == 1);

            await hub.Unsubscribe <MyMessage>(OnMyMessageHandler);

            //hub.Unsubscribe<MyMessage>(OnMyMessageHandler2);
            //hub.Unsubscribe<MyMessage>(OnMyMessageHandler3);
        }
示例#4
0
        // timeout to wait for a subscriber - your message can be queued and wait until someone subscribed and processed it
        public async Task DeliverAtLeastOnceDelayedExample()
        {
            var hub = new MetaPubSub();

            // a subscriber that will subscribe after the message has been published
            var t = Task.Run(async() =>
            {
                await Task.Delay(1500);
                Console.WriteLine($"Subscribed to MyMessage at {DateTime.Now:HH:mm:ss.fff}");
                hub.Subscribe <MyMessage>(OnMyMessage);
            });

            // the message has the 10 seconds timeout and can wait until the subscriber come
            var message = new MyMessage
            {
                DeliverAtLeastOnce       = true, // this must be set to true
                WaitForSubscriberTimeout = 10_000
            };

            Console.WriteLine($"Start publishing and awaiting at {DateTime.Now:HH:mm:ss.fff}");
            // this method will wait until the subscriber receives the message or until timeout expired (10 seconds)
            await hub.Publish(message);

            Console.WriteLine($"End awaiting at {DateTime.Now:HH:mm:ss.fff}");

            await hub.Unsubscribe <MyMessage>(OnMyMessage);
        }
示例#5
0
        // at least once delivery check
        async Task AtLeastOnceDeliveryExample()
        {
            var hub = new MetaPubSub();

            var message = new MyMessage
            {
                // if this not set, NoSubscribersException will not be thrown
                DeliverAtLeastOnce = true
            };

            try
            {
                // publishing a message when no one is subscribed
                await hub.Publish(message);
            }
            catch (NoSubscribersException ex)
            {
                // no one is listening
                Console.WriteLine($"Exception {ex.GetType()}: {ex.Message}");
            }

            hub.Subscribe <MyMessage>(OnMyMessage);
            await hub.Publish(message);

            await hub.Unsubscribe <MyMessage>(OnMyMessage);
        }
示例#6
0
        // subscribes on server and receives a message
        public async Task SendMessageToClient()
        {
            var pipeName             = Guid.NewGuid().ToString();
            var clientConnectedEvent = new ManualResetEventSlim();
            var @event    = new ManualResetEventSlim();
            int recvCount = 0;

            Task Handler(MyMessage x)
            {
                if (++recvCount == 10)
                {
                    @event.Set();
                }
                return(Task.CompletedTask);
            }

            // creating remote hub
            var t = Task.Run(async() =>
            {
                var hub = new MetaPubSub();
                hub.StartServer(pipeName);

                // wait for the subscriber
                clientConnectedEvent.Wait(5000);

                // publishing a message at the remote hub
                for (int i = 0; i < 10; i++)
                {
                    await hub.Publish(new MyMessage());
                }
            });

            // local hub creation
            var hub = new MetaPubSub();
            await hub.ConnectToServer(pipeName);

            await hub.SubscribeOnServer <MyMessage>(Handler);

            // delay allowing the server to process the subscription request
            await Task.Delay(100);

            clientConnectedEvent.Set();

            @event.Wait(5000);

            // unsubscribing
            await hub.Unsubscribe <MyMessage>(Handler);

            Assert.IsTrue(@event.IsSet && recvCount == 10);
        }
示例#7
0
        async Task BasicExample()
        {
            // hub creation
            var hub = new MetaPubSub();

            // subscribing to MyMessage
            hub.Subscribe <MyMessage>(OnMyMessage);

            // publishing a message
            await hub.Publish(new MyMessage());

            // unsubscribing
            await hub.Unsubscribe <MyMessage>(OnMyMessage);
        }
示例#8
0
        // exceptions handling - all exceptions raised when a message processing by subscribers can be caught by the publisher as an AggregateException
        async Task ExceptionHandlingExample()
        {
            var hub = new MetaPubSub();

            try
            {
                var message = new MyMessage
                {
                    DeliverAtLeastOnce = true,
                };

                // publishing a message when no one subscribed - NoSubscribersException
                //await hub.Publish(message);

                // publishing a message when no one subscribed and Timeout > 0 - TimeoutException
                //message.Timeout = 100;
                //await hub.Publish(message);

                hub.Subscribe <MyMessage>(OnMyMessageHandlerWithException);

                // publishing a message
                await hub.Publish(message);
            }
            catch (NoSubscribersException ex)
            {
                // No one is subscribed to this message and (message.DeliverAtLeastOnce == true and message.Timeout == 0)
                Console.WriteLine($"Exception {ex.GetType()}: {ex.Message}");
            }
            catch (TimeoutException ex)
            {
                // No one is subscribed to this message and (message.DeliverAtLeastOnce == true and message.Timeout > 0)
                Console.WriteLine($"Exception {ex.GetType()}: {ex.Message}");
            }
            catch (AggregateException ex)
            {
                // All exceptions raised when a message processing by subscribers
                // can be caught by the publisher as an AggregateException.
                // If some of the subscribers throw an exception, other subscribers
                // continues to process the message.
                Console.WriteLine($"Exception {ex.GetType()}: {ex.Message}");
                foreach (var innerEx in ex.InnerExceptions)
                {
                    Console.WriteLine($"\tInner Exception {innerEx.GetType()}: {innerEx.Message}");
                }
            }

            await hub.Unsubscribe <MyMessage>(OnMyMessageHandlerWithException);
        }
示例#9
0
        async Task BasicExample()
        {
            int count = 0;

            Task Handler(MyMessage x)
            {
                count++;
                return(Task.CompletedTask);
            }

            // Creating the server hub.
            // The server and the client hubs should be created in separate processes,
            // this example is for demo only.
            var serverHub = new MetaPubSub();

            // Starting the hub as a server named 'Meta'.
            serverHub.StartServer("Meta");

            // Client hub creation. There are can be several hubs connected to the same server.
            var clientHub = new MetaPubSub();

            // Connecting to the remote server.
            await clientHub.ConnectToServer("Meta");

            // Subscribing to MyMessage on the server and locally at the same time.
            await clientHub.SubscribeOnServer <MyMessage>(Handler);

            // The server publishes a message.
            await serverHub.Publish(new MyMessage());

            // Client hub publishes a message and it will be received locally without being sent to the server.
            await clientHub.Publish(new MyMessage());

            // Client hub sends a message to the server where it will be published and sent back.
            await clientHub.PublishOnServer(new MyMessage());

            // All three messages should be received.
            Debug.Assert(count == 3);

            // Unsubscribing both on the server-side and locally.
            await clientHub.Unsubscribe <MyMessage>(Handler);
        }
示例#10
0
        public async Task Predicate()
        {
            var hub = new MetaPubSub();

            hub.Subscribe <MyMessage>(OnMyMessageHandler, OnMyMessagePredicate);

            var message = new MyMessage {
                LogSeverity = MetaLogErrorSeverity.Info
            };
            await hub.Publish(message);

            Assert.IsTrue(message.DeliveredCount == 0);

            message = new MyMessage {
                LogSeverity = MetaLogErrorSeverity.Error
            };
            await hub.Publish(message);

            Assert.IsTrue(message.DeliveredCount == 1);

            await hub.Unsubscribe <MyMessage>(OnMyMessageHandler);
        }
示例#11
0
        // scheduling a message - your message can be queued and published after a time delay
        public async Task ScheduleExample()
        {
            var hub = new MetaPubSub();

            hub.Subscribe <MyMessage>(OnMyMessage);

            var message = new MyMessage
            {
                DeliverAtLeastOnce       = true,
                WaitForSubscriberTimeout = 1500
            };

            // The message will be published after 3 seconds delay and after that, it can wait another 500 ms for a subscriber.
            // When using Schedule method there is no way to receive NoSubscriberException or AggregateException.
            hub.Schedule(message, millisecondsDelay: 3000);
            Console.WriteLine($"Message scheduled at {DateTime.Now:HH:mm:ss.fff}, delay - 3 sec");

            // waiting before unsubscribing
            await Task.Delay(3500);

            await hub.Unsubscribe <MyMessage>(OnMyMessage);
        }
示例#12
0
        // Should get the NoSubscribersException if message is filtered and DeliverAtLeastOnce = true
        public async Task Test_DeliverAtLeastOnce_Filtered()
        {
            var  hub = new MetaPubSub();
            bool noSubscriberException = false;

            hub.Subscribe <MyMessage>(OnMyMessageHandler, OnMyMessagePredicate);

            var message = new MyMessage {
                LogSeverity = MetaLogErrorSeverity.Info, DeliverAtLeastOnce = true
            };

            try
            {
                await hub.Publish(message);
            }
            catch (NoSubscribersException)
            {
                noSubscriberException = true;
            }
            Assert.IsTrue(noSubscriberException);
            Assert.IsTrue(message.DeliveredCount == 0);

            await hub.Unsubscribe <MyMessage>(OnMyMessageHandler);
        }
示例#13
0
        // subscribed twice but delivered only once
        public async Task Basic()
        {
            var hub = new MetaPubSub();

            var message = new MyMessage();
            await hub.Publish(message);

            Assert.IsTrue(message.DeliveredCount == 0);

            hub.Subscribe <MyMessage>(OnMyMessageHandler);
            hub.Subscribe <MyMessage>(OnMyMessageHandler);

            message = new MyMessage();
            await hub.Publish(message);

            Assert.IsTrue(message.DeliveredCount == 1);

            await hub.Unsubscribe <MyMessage>(OnMyMessageHandler);

            message = new MyMessage();
            await hub.Publish(message);

            Assert.IsTrue(message.DeliveredCount == 0);
        }