Exemple #1
0
        public async Task Given_subscribed_with_overlapping_wildcards_async_using_handler_It_should_get_only_subcription_messages()
        {
            const string subjectNs = "foo.tests.";

            _sync   = Sync.MaxOne();
            _client = await Context.ConnectClientAsync();

            // First subscription
            await _client.SubAsync(subjectNs + ">");

            // Second, overlapping subscription
            var subscription = await _client.SubAsync(subjectNs + "*", stream => stream.Subscribe(msg => _sync.Release(msg)));

            await Context.DelayAsync();

            await _client.PubAsync(subjectNs + "type1", "Test1");

            _sync.WaitForAny();
            await _client.PubAsync(subjectNs + "type2", "Test2");

            _sync.WaitForAny();
            await _client.PubAsync(subjectNs + "type3", "Test3");

            _sync.WaitForAny();

            _sync.InterceptedCount.Should().Be(3);
            _sync.Intercepted.Select(i => i.SubscriptionId).Should().OnlyContain(i => i == subscription.SubscriptionInfo.Id);
        }
Exemple #2
0
        public async Task Given_subscribed_async_using_handler_When_the_subscription_has_been_disposed_It_should_not_get_messages()
        {
            var subject = Context.GenerateSubject();

            _sync   = Sync.MaxOne();
            _client = await Context.ConnectClientAsync();

            var s = await _client.SubAsync(subject, stream => stream.Subscribe(msg => _sync.Release(msg)));

            await Context.DelayAsync();

            await _client.PubAsync(subject, "Test1");

            _sync.WaitForAny();
            await _client.PubAsync(subject, "Test2");

            _sync.WaitForAny();

            s.Dispose();

            await _client.PubAsync(subject, "Test3");

            await Context.DelayAsync();

            _sync.InterceptedCount.Should().Be(2);
        }
        /// <summary>
        /// Starts the subscription
        /// </summary>
        /// <summary>
        /// Starts the subscription
        /// </summary>
        public async Task Start()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException($"{typeof(JsonRpcSubscription).FullName}@{this.GetHashCode()}");
            }
            if (!_client.IsConnected)
            {
                _client.Connect();
            }
            if (_subscription != null)
            {
                await _client.UnsubAsync(_subscription);

                _subscription = null;
            }
            _subscription = await _client.SubAsync(_sInfo, stream => stream.Subscribe(msg =>
            {
                try
                {
                    byte[] resp = OnMessage(msg.Payload);
                    _client.Pub(msg.ReplyTo, resp);
                }
                catch (Exception ex)
                {
                    _logger?.LogError(ex, "Error publishing NATS message");
                }
            }, error => {
                _logger?.LogError(error, "Fatal error in NATS subscription handler");
            }));
        }
        public static async Task RunAsync(ConnectionInfo cnInfo)
        {
            using (var client = new NatsClient("Sample8", cnInfo))
            {
                //Subscribe directly to MsgOpStream
                client.MsgOpStream
                .Where(msgOp => msgOp.Subject == "demo.a")
                .Select(msgOp => msgOp.GetPayloadAsString())
                .Subscribe(msg => Console.WriteLine($"A: {msg}"));

                client.MsgOpStream
                .Where(msgOp => msgOp.Subject == "demo.b")
                .Select(msgOp => msgOp.GetPayloadAsString())
                .Subscribe(msg => Console.WriteLine($"B: {msg}"));

                //OpStream gets all incoming Ops. Like MsgOp, Ping, Pong...
                client.OpStream
                .OfType <MsgOp>()
                .Select(msgOp => msgOp.GetAsString().Length)
                .Subscribe(len => Console.WriteLine($"Len: {len}"));

                client.Connect();

                //Tell NATS server we are interested in all subjects
                //under "demo". So we only have one NATS Server subscription
                await client.SubAsync("demo.>");

                Console.WriteLine("Hit key to quit.");
                Console.ReadKey();
            }
        }
Exemple #5
0
        public async Task Client_Should_be_able_to_handle_large_message_When_using_explicit_flush_although_auto_flush(int messageCount)
        {
            var message    = new string('b', 16384);
            var exceptions = new List <Exception>();
            var subject    = Context.GenerateSubject();
            var cnInfo     = Context.GetConnectionInfo();

            cnInfo.PubFlushMode = PubFlushMode.Auto;

            _sync    = Sync.Max(messageCount);
            _client1 = await Context.ConnectClientAsync(cnInfo);

            _client1.Events.OfType <ClientWorkerFailed>().Subscribe(ev => exceptions.Add(ev.Exception));
            _client1.OpStream.OfType <MsgOp>().SubscribeSafe(msg => _sync.Release(msg), ex => exceptions.Add(ex));
            await _client1.SubAsync(subject);

            await Context.DelayAsync();

            for (var i = 0; i < messageCount; i++)
            {
                await _client1.PubAsync(subject, message);

                await _client1.FlushAsync();
            }

            _sync.WaitForAll();

            exceptions.Should().BeEmpty();
            _sync.InterceptedCount.Should().Be(messageCount);
            _sync.Intercepted
            .Select(m => m.GetPayloadAsString())
            .Should().OnlyContain(m => m == message);
        }
Exemple #6
0
        public async Task Client_Should_dispatch_to_all_subscribed_clients()
        {
            const string subject         = "Test";
            var          nr2ReceiveCount = 0;
            var          nr3ReceiveCount = 0;

            _client2.OpStream.OfType <MsgOp>().Subscribe(msg =>
            {
                Interlocked.Increment(ref nr2ReceiveCount);
                ReleaseOne();
            });
            _client2.Sub(subject);

            _client3.OpStream.OfType <MsgOp>().Subscribe(msg =>
            {
                Interlocked.Increment(ref nr3ReceiveCount);
                ReleaseOne();
            });
            await _client3.SubAsync(subject);

            _client1.Pub(subject, "mess1");
            WaitOne();
            WaitOne();

            await _client1.PubAsync(subject, "mess2");

            WaitOne();
            WaitOne();

            nr2ReceiveCount.Should().Be(2);
            nr3ReceiveCount.Should().Be(2);
        }
Exemple #7
0
        public async Task Given_not_connected_Should_be_able_to_subscribe_async()
        {
            _client = Context.CreateClient();

            var sub = await _client.SubAsync(Context.GenerateSubject());

            sub.Should().NotBeNull();
            _client.IsConnected.Should().BeFalse();
        }
Exemple #8
0
        public async Task Given_subscribed_async_using_observer_and_subscribed_to_other_subject_as_well_It_should_only_get_subject_specific_messages()
        {
            var subject             = GenerateSubject();
            var otherSubject        = subject + "fail";
            var interceptedSubjects = new List <string>();

            await _client.SubAsync(subject, stream => stream.Subscribe(msg =>
            {
                interceptedSubjects.Add(msg.Subject);
                ReleaseOne();
            }));

            _client.Sub(otherSubject, stream => stream.Subscribe(msg => ReleaseOne()));

            await _client.PubAsync(subject, "Test1");

            WaitOne();
            await _client.PubAsync(subject, "Test2");

            WaitOne();
            await _client.PubAsync(otherSubject, "Test3");

            WaitOne();

            interceptedSubjects.Should().HaveCount(2);
            interceptedSubjects.Should().OnlyContain(i => i == subject);
        }
Exemple #9
0
        public async Task Client_Should_not_reconnect_after_failure_When_not_configured_to_do_so()
        {
            var subject = Context.GenerateSubject();
            var wasDisconnectedDueToFailure = false;
            var wasReconnected = false;

            var ex             = new Exception("This will destroy things.");
            var throwingLogger = new Mock <ILogger>();

            throwingLogger.Setup(f => f.Error(It.IsAny <string>(), It.IsAny <Exception>())).Throws(ex);
            LoggerManager.Resolve = type => throwingLogger.Object;

            _sync = Sync.MaxTwo();

            var cnInfo = Context.GetConnectionInfo();

            cnInfo.AutoReconnectOnFailure = false;
            _client = new NatsClient(cnInfo);
            await _client.ConnectAsync();

            await _client.SubAsync(subject);

            _client.Events
            .OfType <ClientDisconnected>()
            .Where(ev => ev.Reason == DisconnectReason.DueToFailure)
            .Subscribe(ev =>
            {
                wasDisconnectedDueToFailure = true;
                _sync.Release();
            });

            _client.Events
            .OfType <ClientConnected>()
            .Subscribe(ev =>
            {
                wasReconnected = true;
                _sync.Release();
            });

            _client.MsgOpStream.Subscribe(msg => throw new Exception("Fail"));

            await Context.DelayAsync();

            await _client.PubAsync(subject, "This message will fail");

            //Wait for the Disconnected release and the potential Connected release
            _sync.WaitForAny();

            wasDisconnectedDueToFailure.Should().BeTrue();
            wasReconnected.Should().BeFalse();
            _client.IsConnected.Should().BeFalse();
        }
Exemple #10
0
        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                try
                {
                    ConnectionInfo cnInfo = new ConnectionInfo(_settings.Value.BusConnectionString);
                    using (NatsClient natsClient = new NatsClient(cnInfo))
                    {
                        if (!natsClient.IsConnected)
                        {
                            natsClient.Connect();
                        }

                        await natsClient.SubAsync(_settings.Value.CandlesQueueName, stream => stream.Subscribe(msg =>
                        {
                            try
                            {
                                Task.Run(async() => await Process(msg, natsClient));
                            }
                            catch (Exception ex)
                            {
                                _logger.LogError($"TradingProcessor failed with message: {ex.Message}", ex);
                            }
                        }));

                        natsClient.Events.OfType <ClientDisconnected>().Subscribe(ev =>
                        {
                            Console.WriteLine($"Client was disconnected due to reason '{ev.Reason}'");

                            if (!cnInfo.AutoReconnectOnFailure)
                            {
                                ev.Client.Connect();
                            }
                        });

                        while (!stoppingToken.IsCancellationRequested)
                        {
                            await Task.Delay(TimeSpan.FromSeconds(1));
                        }

                        natsClient.Disconnect();
                    }
                }
                catch (Exception ex)
                {
                    _logger.LogError(ex.Message);
                }
            }
        }
        public async Task Should_be_able_to_publish_and_consume_JSON_payloads_asynchronously()
        {
            var orgItem = EncodingTestItem.Create();
            EncodingTestItem decodedItem = null;

            await _client.SubAsync("ClientProtobufEncodingTests", stream => stream.Subscribe(msg =>
            {
                decodedItem = msg.FromJson <EncodingTestItem>();
                ReleaseOne();
            }));

            await _client.PubAsJsonAsync("ClientProtobufEncodingTests", orgItem);

            WaitOne();

            orgItem.Should().BeEquivalentTo(decodedItem);
        }
        public async Task Client_Should_dispatch_to_all_subscribed_clients()
        {
            var subject    = Context.GenerateSubject();
            var nr1Receive = new ConcurrentQueue <MsgOp>();
            var nr2Receive = new ConcurrentQueue <MsgOp>();
            var nr3Receive = new ConcurrentQueue <MsgOp>();

            _sync    = Sync.MaxTwo();
            _client1 = await Context.ConnectClientAsync();

            _client2 = await Context.ConnectClientAsync();

            _client3 = await Context.ConnectClientAsync();

            _client1.OpStream.OfType <MsgOp>().Subscribe(msg => nr1Receive.Enqueue(msg));

            _client2.OpStream.OfType <MsgOp>().Subscribe(msg =>
            {
                nr2Receive.Enqueue(msg);
                _sync.Release(msg);
            });
            _client2.Sub(subject);

            _client3.OpStream.OfType <MsgOp>().Subscribe(msg =>
            {
                nr3Receive.Enqueue(msg);
                _sync.Release(msg);
            });
            await _client3.SubAsync(subject);

            await Context.DelayAsync();

            _client1.Pub(subject, "mess1");
            _sync.WaitForAll();

            await _client1.PubAsync(subject, "mess2");

            _sync.WaitForAll();

            _sync.InterceptedCount.Should().Be(4);
            nr1Receive.Count.Should().Be(0);
            nr2Receive.Count.Should().Be(2);
            nr3Receive.Count.Should().Be(2);
        }
        public async Task Client_Should_not_reconnect_after_failure_When_not_configured_to_do_so()
        {
            const string subject = "test";
            var          wasDisconnectedDueToFailure = false;
            var          wasReconnected = false;

            var ex             = new Exception("This will destroy things.");
            var throwingLogger = new Mock <ILogger>();

            throwingLogger.Setup(f => f.Error(It.Is <string>(m => m == "Error in observer while emitting value."), It.IsAny <Exception>())).Throws(ex);
            LoggerManager.Resolve = type => throwingLogger.Object;

            _client = new NatsClient(_cnInfoWithNoAutoReconnect);
            _client.Connect();

            await _client.SubAsync(subject);

            _client.Events.OfType <ClientDisconnected>()
            .Where(ev => ev.Reason == DisconnectReason.DueToFailure)
            .Subscribe(ev =>
            {
                wasDisconnectedDueToFailure = true;
                ReleaseOne();
            });

            _client.Events.OfType <ClientConnected>()
            .Subscribe(ev =>
            {
                wasReconnected = true;
                ReleaseOne();
            });

            _client.MsgOpStream.Subscribe(msg => throw new Exception("Fail"));

            await _client.PubAsync(subject, "This message will fail");

            //Wait for the Disconnected release and the potential Connected release
            WaitOne();
            WaitOne();

            wasDisconnectedDueToFailure.Should().BeTrue();
            wasReconnected.Should().BeFalse();
            _client.IsConnected.Should().BeFalse();
        }
        public async Task Should_be_able_to_publish_and_consume_JSON_payloads_asynchronously()
        {
            var subject = Context.GenerateSubject();
            var orgItem = EncodingTestItem.Create();
            EncodingTestItem decodedItem = null;

            _sync   = Sync.MaxOne();
            _client = await Context.ConnectClientAsync();

            await _client.SubAsync(subject, stream => stream.Subscribe(msg =>
            {
                decodedItem = msg.FromJson <EncodingTestItem>();
                _sync.Release();
            }));

            await _client.PubAsJsonAsync(subject, orgItem);

            _sync.WaitForAll();

            orgItem.Should().BeEquivalentTo(decodedItem);
        }
Exemple #15
0
        public async Task Given_subscribed_async_using_observer_and_subscribed_to_other_subject_as_well_It_should_only_get_subject_specific_messages()
        {
            var subject                  = Context.GenerateSubject();
            var otherSubject             = subject + "fail";
            var interceptedSubjects      = new List <string>();
            var interceptedOtherSubjects = new List <string>();

            _sync   = Sync.MaxTwo();
            _client = await Context.ConnectClientAsync();

            await _client.SubAsync(subject, stream => stream.Subscribe(msg =>
            {
                interceptedSubjects.Add(msg.Subject);
                _sync.Release();
            }));

            _client.Sub(otherSubject, stream => stream.Subscribe(msg =>
            {
                interceptedOtherSubjects.Add(msg.Subject);
                _sync.Release();
            }));

            await Context.DelayAsync();

            await _client.PubAsync(subject, "Test1");

            _sync.WaitForAny();
            await _client.PubAsync(subject, "Test2");

            _sync.WaitForAny();
            await _client.PubAsync(otherSubject, "Test3");

            _sync.WaitForAny();

            interceptedSubjects.Should().HaveCount(2);
            interceptedSubjects.Should().OnlyContain(i => i == subject);
            interceptedOtherSubjects.Should().HaveCount(1);
            interceptedOtherSubjects.Should().OnlyContain(i => i == otherSubject);
        }
        public async Task Client_Should_not_reconnect_When_user_initiated_disconnect()
        {
            const string subject = "test";
            var          wasDisconnectedDueToFailure = false;
            var          wasDisconnected             = false;
            var          wasReconnected = false;

            _client = new NatsClient(_cnInfoWithAutoReconnect);
            _client.Connect();

            await _client.SubAsync(subject);

            _client.Events.OfType <ClientDisconnected>()
            .Subscribe(ev =>
            {
                wasDisconnectedDueToFailure = ev.Reason == DisconnectReason.DueToFailure;
                wasDisconnected             = true;
                ReleaseOne();
            });

            _client.Events.OfType <ClientConnected>()
            .Subscribe(ev =>
            {
                wasReconnected = true;
                ReleaseOne();
            });

            _client.Disconnect();

            //Wait for the Disconnected release and the potentiall Connected release
            WaitOne();
            WaitOne();

            wasDisconnectedDueToFailure.Should().BeFalse();
            wasDisconnected.Should().BeTrue();
            wasReconnected.Should().BeFalse();
            _client.IsConnected.Should().BeFalse();
        }
Exemple #17
0
        public async Task Given_subscribed_with_wildcard_async_using_handler_It_should_get_messages()
        {
            const string subjectNs = "foo.tests.";

            _sync   = Sync.MaxOne();
            _client = await Context.ConnectClientAsync();

            await _client.SubAsync(subjectNs + "*", stream => stream.Subscribe(msg => _sync.Release(msg)));

            await Context.DelayAsync();

            await _client.PubAsync(subjectNs + "type1", "Test1");

            _sync.WaitForAny();
            await _client.PubAsync(subjectNs + "type2", "Test2");

            _sync.WaitForAny();
            await _client.PubAsync(subjectNs + "type3", "Test3");

            _sync.WaitForAny();

            _sync.InterceptedCount.Should().Be(3);
            _sync.Intercepted.Select(i => i.Subject).Should().OnlyContain(i => i.StartsWith(subjectNs));
        }