public async Task Client_Should_be_able_to_publish_and_consume_messages_When_publishing_one_by_one() { var subject = Context.GenerateSubject(); var messages = new[] { "My test string\r\nwith two lines and\ttabs!", "Foo bar!", "My async test string\r\nwith two lines and\ttabs!", "Async Foo bar!" }; _sync = Sync.Max(4); _client1 = await Context.ConnectClientAsync(); _client1.MsgOpStream.Subscribe(msg => _sync.Release(msg)); _client1.Sub(subject); await Context.DelayAsync(); _client1.Pub(subject, messages[0]); _client1.Pub(subject, Encoding.UTF8.GetBytes(messages[1])); await _client1.PubAsync(subject, messages[2]); await _client1.PubAsync(subject, Encoding.UTF8.GetBytes(messages[3])); _sync.WaitForAll(); _sync.InterceptedCount.Should().Be(messages.Length); _sync.Intercepted.Select(m => m.GetPayloadAsString()).ToArray().Should().Contain(messages); }
public async Task Client_Should_throw_if_pub_after_disconnected() { var subject = Context.GenerateSubject(); var body = new byte[0]; _client1 = await Context.ConnectClientAsync(); // Succeeds _client1.Pub(subject, "body"); _client1.Pub(subject, "body", "repy.to.subject"); _client1.Pub(subject, body.AsMemory()); _client1.Pub(subject, body.AsMemory(), "repy.to.subject"); // Disconnect from NATS per user request _client1.Disconnect(); Assert.False(_client1.IsConnected); // Fails after being disconnected Should.ThrowNatsException(() => _client1.Pub(subject, "body")); Should.ThrowNatsException(() => _client1.Pub(subject, "body", "reply.to.subject")); Should.ThrowNatsException(() => _client1.Pub(subject, body.AsMemory())); Should.ThrowNatsException(() => _client1.Pub(subject, body.AsMemory(), "reply.to.subject")); await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, "body")); await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, "body", "reply.to.subject")); await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, body.AsMemory())); await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, body.AsMemory(), "reply.to.subject")); }
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); }
public async Task Given_subscribed_When_unsubscribing_async_It_should_not_get_any_further_messages() { var subject = Context.GenerateSubject(); _sync = Sync.MaxOne(); _client = await Context.ConnectClientAsync(); var s = _client.Sub(subject, stream => stream.Subscribe(NatsObserver.Delegating <MsgOp>(msg => _sync.Release(msg)))); await Context.DelayAsync(); await _client.PubAsync(subject, "Test1"); _sync.WaitForAny(); await _client.PubAsync(subject, "Test2"); _sync.WaitForAny(); await _client.UnsubAsync(s.SubscriptionInfo); await _client.PubAsync(subject, "Test3"); await Context.DelayAsync(); _sync.InterceptedCount.Should().Be(2); }
public async Task Client_Should_be_able_to_publish_When_no_subscribers_exists() { _client1 = await Context.ConnectClientAsync(); _client1.Pub("Test", "test message"); await _client1.PubAsync("Test", "Test message"); }
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 static async Task RunAsync(ConnectionInfo cnInfo) { using (var client = new NatsClient("Publisher", cnInfo)) { client.Connect(); while (true) { Console.WriteLine("Say what? (blank=quit)"); var message = Console.ReadLine(); if (string.IsNullOrWhiteSpace(message)) { break; } Console.WriteLine("To what \"Child\" Subject? (blank=quit)"); var subject = Console.ReadLine(); if (string.IsNullOrWhiteSpace(subject)) { break; } await client.PubAsync($"demo.{subject}", message); } } }
public async Task Client_Should_throw_if_pub_when_never_connected() { var subject = Context.GenerateSubject(); var body = new byte[0]; _client1 = Context.CreateClient(); Should.ThrowNatsException(() => _client1.Pub(subject, "body")); Should.ThrowNatsException(() => _client1.Pub(subject, "body", "reply.to.subject")); Should.ThrowNatsException(() => _client1.Pub(subject, body.AsMemory())); Should.ThrowNatsException(() => _client1.Pub(subject, body.AsMemory(), "reply.to.subject")); await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, "body")); await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, "body", "reply.to.subject")); await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, body.AsMemory())); await Should.ThrowNatsExceptionAsync(() => _client1.PubAsync(subject, body.AsMemory(), "reply.to.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(); }
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 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)); }
public async Task Given_subscribed_When_disconnectiong_and_connecting_again_It_should_resubscribe_and_get_messages() { var subject = Context.GenerateSubject(); _sync = Sync.MaxOne(); _client = await Context.ConnectClientAsync(); _client.Sub(subject, stream => stream.Subscribe(NatsObserver.Delegating <MsgOp>(msg => _sync.Release(msg)))); await Context.DelayAsync(); await _client.PubAsync(subject, "Test1"); _sync.WaitForAny(); _client.Disconnect(); await _client.ConnectAsync(); await _client.PubAsync(subject, "Test2"); _sync.WaitForAny(); _sync.InterceptedCount.Should().Be(2); }
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 Given_subscribed_sync_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>(); _client.Sub(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); }