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); }
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(); } }
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); }
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); }
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(); }
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); }
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(); }
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); }
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(); }
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)); }