Example #1
0
        public void TestAckTerm()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                PullSubscribeOptions options   = PullSubscribeOptions.Builder().WithDurable(DURABLE).Build();
                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, options);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                // TERM
                JsPublish(js, SUBJECT, "TERM", 1);

                sub.Pull(1);
                Msg message = sub.NextMessage(1000);
                Assert.NotNull(message);
                Assert.Equal("TERM1", Encoding.ASCII.GetString(message.Data));
                message.Term();

                sub.Pull(1);
                AssertNoMoreMessages(sub);
            });
        }
Example #2
0
        public void TestBindPull()
        {
            Context.RunInJsServer(c =>
            {
                CreateDefaultTestStream(c);
                IJetStream js = c.CreateJetStreamContext();

                JsPublish(js, SUBJECT, 1, 1);

                PullSubscribeOptions pso = PullSubscribeOptions.Builder()
                                           .WithDurable(DURABLE)
                                           .Build();
                IJetStreamPullSubscription s = js.PullSubscribe(SUBJECT, pso);
                s.Pull(1);
                Msg m = s.NextMessage(1000);
                Assert.NotNull(m);
                Assert.Equal(Data(1), Encoding.ASCII.GetString(m.Data));
                m.Ack();
                s.Unsubscribe();

                JsPublish(js, SUBJECT, 2, 1);
                pso = PullSubscribeOptions.Builder()
                      .WithStream(STREAM)
                      .WithDurable(DURABLE)
                      .WithBind(true)
                      .Build();
                s = js.PullSubscribe(SUBJECT, pso);
                s.Pull(1);
                m = s.NextMessage(1000);
                Assert.NotNull(m);
                Assert.Equal(Data(2), Encoding.ASCII.GetString(m.Data));
                m.Ack();
                s.Unsubscribe();

                JsPublish(js, SUBJECT, 3, 1);
                pso = PullSubscribeOptions.BindTo(STREAM, DURABLE);
                s   = js.PullSubscribe(SUBJECT, pso);
                s.Pull(1);
                m = s.NextMessage(1000);
                Assert.NotNull(m);
                Assert.Equal(Data(3), Encoding.ASCII.GetString(m.Data));
            });
        }
Example #3
0
        public void TestAckWaitTimeout()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                ConsumerConfiguration cc = ConsumerConfiguration.Builder()
                                           .WithAckWait(1500)
                                           .Build();
                PullSubscribeOptions pso = PullSubscribeOptions.Builder()
                                           .WithDurable(DURABLE)
                                           .WithConfiguration(cc)
                                           .Build();
                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, pso);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                // Ack Wait timeout
                JsPublish(js, SUBJECT, "WAIT", 1);

                sub.Pull(1);
                Msg message = sub.NextMessage(1000);
                Assert.NotNull(message);
                Assert.Equal("WAIT1", Encoding.ASCII.GetString(message.Data));
                Thread.Sleep(2000);

                sub.Pull(1);
                message = sub.NextMessage(1000);
                Assert.NotNull(message);
                Assert.Equal("WAIT1", Encoding.ASCII.GetString(message.Data));

                sub.Pull(1);
                AssertNoMoreMessages(sub);
            });
        }
Example #4
0
        public void TestPullExpires()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                PullSubscribeOptions options = PullSubscribeOptions.Builder().WithDurable(DURABLE).Build();

                // Subscribe synchronously.
                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, options);
                AssertSubscription(sub, STREAM, DURABLE, null, true);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                int expires = 250;       // millis

                // publish 10 messages
                JsPublish(js, SUBJECT, "A", 5);
                sub.PullExpiresIn(10, expires);
                IList <Msg> messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);
                AssertAllJetStream(messages);
                Thread.Sleep(expires); // make sure the pull actually expires

                JsPublish(js, SUBJECT, "B", 10);
                sub.PullExpiresIn(10, expires);
                messages = ReadMessagesAck(sub);
                Assert.Equal(10, messages.Count);
                Thread.Sleep(expires); // make sure the pull actually expires

                JsPublish(js, SUBJECT, "C", 5);
                sub.PullExpiresIn(10, expires);
                messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);
                AssertAllJetStream(messages);
                Thread.Sleep(expires); // make sure the pull actually expires

                JsPublish(js, SUBJECT, "D", 10);
                sub.Pull(10);
                messages = ReadMessagesAck(sub);
                Assert.Equal(10, messages.Count);

                JsPublish(js, SUBJECT, "E", 5);
                sub.PullExpiresIn(10, expires); // using millis version here
                messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);
                AssertAllJetStream(messages);
                Thread.Sleep(expires); // make sure the pull actually expires

                JsPublish(js, SUBJECT, "F", 10);
                sub.PullNoWait(10);
                messages = ReadMessagesAck(sub);
                Assert.Equal(10, messages.Count);

                JsPublish(js, SUBJECT, "G", 5);
                sub.PullExpiresIn(10, expires); // using millis version here
                messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);
                AssertAllJetStream(messages);

                JsPublish(js, SUBJECT, "H", 10);
                messages = sub.Fetch(10, expires);
                Assert.Equal(10, messages.Count);
                AssertAllJetStream(messages);

                JsPublish(js, SUBJECT, "I", 5);
                sub.PullExpiresIn(10, expires);
                messages = ReadMessagesAck(sub);
                Assert.Equal(5, messages.Count);
                AssertAllJetStream(messages);
                Thread.Sleep(expires); // make sure the pull actually expires
            });
        }
Example #5
0
        public void TestBasic()
        {
            Context.RunInJsServer(c =>
            {
                // create the stream.
                CreateDefaultTestStream(c);

                // Create our JetStream context.
                IJetStream js = c.CreateJetStreamContext();

                // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                PullSubscribeOptions options = PullSubscribeOptions.Builder().WithDurable(DURABLE).Build();

                // Pull Subscribe.
                IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, options);
                AssertSubscription(sub, STREAM, DURABLE, null, true);
                c.Flush(DefaultTimeout); // flush outgoing communication with/to the server

                // publish some amount of messages, but not entire pull size
                JsPublish(js, SUBJECT, "A", 4);

                // start the pull
                sub.Pull(10);

                // read what is available, expect 4
                IList <Msg> messages = ReadMessagesAck(sub);
                int total            = messages.Count;
                ValidateRedAndTotal(4, messages.Count, 4, total);

                // publish some more covering our initial pull and more
                JsPublish(js, SUBJECT, "B", 10);

                // read what is available, expect 6 more
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(6, messages.Count, 10, total);

                // read what is available, should be zero since we didn't re-pull
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(0, messages.Count, 10, total);

                // re-issue the pull
                sub.Pull(10);

                // read what is available, should be 4 left over
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(4, messages.Count, 14, total);

                // publish some more
                JsPublish(js, SUBJECT, "C", 10);

                // read what is available, should be 6 since we didn't finish the last batch
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(6, messages.Count, 20, total);

                // re-issue the pull, but a smaller amount
                sub.Pull(2);

                // read what is available, should be 5 since we changed the pull size
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(2, messages.Count, 22, total);

                // re-issue the pull, since we got the full batch size
                sub.Pull(2);

                // read what is available, should be zero since we didn't re-pull
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(2, messages.Count, 24, total);

                // re-issue the pull, any amount there are no messages
                sub.Pull(1);

                // read what is available, there are none
                messages = ReadMessagesAck(sub);
                total   += messages.Count;
                ValidateRedAndTotal(0, messages.Count, 24, total);
            });
        }
Example #6
0
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive Batch Size", args, Usage)
                                    .DefaultStream("pull-stream")
                                    .DefaultSubject("pull-subject")
                                    .DefaultDurable("pull-durable")
                                    .DefaultCount(15)
                                    .Build();

            try
            {
                using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions()))
                {
                    // Create a JetStreamManagement context.
                    IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                    // Use the utility to create a stream stored in memory.
                    JsUtils.CreateStreamExitWhenExists(jsm, helper.Stream, helper.Subject);

                    // Create our JetStream context.
                    IJetStream js = c.CreateJetStreamContext();

                    // Start publishing the messages, don't wait for them to finish, simulating an outside producer.
                    JsUtils.PublishInBackground(js, helper.Subject, "pull-message", helper.Count);

                    // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                    PullSubscribeOptions pullOptions = PullSubscribeOptions.Builder()
                                                       .WithDurable(helper.Durable) // required
                                                       .Build();

                    // subscribe
                    IJetStreamPullSubscription sub = js.PullSubscribe(helper.Subject, pullOptions);
                    c.Flush(1000);

                    bool keepGoing = true;
                    int  red       = 0;
                    while (keepGoing && red < helper.Count)
                    {
                        sub.Pull(10);
                        int round = 0;
                        while (keepGoing && round < 10)
                        {
                            try
                            {
                                Msg m = sub.NextMessage(1000); // first message
                                Console.WriteLine($"{++red}. Message: {m}");
                                m.Ack();
                                round++;
                            }
                            catch (NATSTimeoutException) // timeout means there are no messages available
                            {
                                keepGoing = false;
                            }
                        }
                    }

                    // delete the stream since we are done with it.
                    jsm.DeleteStream(helper.Stream);
                }
            }
            catch (Exception ex)
            {
                helper.ReportException(ex);
            }
        }
Example #7
0
        public static void Main(string[] args)
        {
            ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive Batch Size, Use Cases", args, Usage)
                                    .DefaultStream("pull-stream")
                                    .DefaultSubject("pull-subject")
                                    .DefaultDurable("pull-durable")
                                    .Build();

            try
            {
                using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions()))
                {
                    // Create a JetStreamManagement context.
                    IJetStreamManagement jsm = c.CreateJetStreamManagementContext();

                    // Use the utility to create a stream stored in memory.
                    JsUtils.CreateStreamExitWhenExists(jsm, helper.Stream, helper.Subject);

                    // Create our JetStream context.
                    IJetStream js = c.CreateJetStreamContext();

                    // Build our subscription options. Durable is REQUIRED for pull based subscriptions
                    PullSubscribeOptions pullOptions = PullSubscribeOptions.Builder()
                                                       .WithDurable(helper.Durable) // required
                                                       .Build();

                    // 0.1 Initialize. subscription
                    // 0.2 Flush outgoing communication with/to the server, useful when app is both JsUtils.Publishing and subscribing.
                    // 0.3 Start the pull, you don't have to call this again because AckMode.NEXT
                    // -  When we ack a batch message the server starts preparing or adding to the next batch.
                    Console.WriteLine("\n----------\n0. Initialize the subscription and pull.");
                    IJetStreamPullSubscription sub = js.PullSubscribe(helper.Subject, pullOptions);
                    c.Flush(1000);

                    sub.Pull(10);

                    // 1. JsUtils.Publish some that is less than the batch size.
                    // -  Do this first as data will typically be published first.
                    Console.WriteLine("----------\n1. JsUtils.Publish some amount of messages, but not entire batch size.");
                    JsUtils.Publish(js, helper.Subject, "A", 4);
                    IList <Msg> messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 4 total messages, we received: " + messages.Count);

                    // 2. JsUtils.Publish some more covering our pull size...
                    // -  Read what is available, expect only 6 b/c 4 + 6 = 10
                    Console.WriteLine("----------\n2. JsUtils.Publish more than the remaining batch size.");
                    JsUtils.Publish(js, helper.Subject, "B", 10);
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 6 total messages, we received: " + messages.Count);

                    // 3. There are still 4 messages from B, but the batch was finished
                    // -  won't get any messages until a pull is issued.
                    Console.WriteLine("----------\n3. Read without re-issue.");
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 0 total messages, we received: " + messages.Count);

                    // 4. re-issue the pull to get the last 4
                    Console.WriteLine("----------\n4. Re-issue to get the last 4.");
                    sub.Pull(10);
                    messages = JsUtils.ReadMessagesAck(sub);
                    Console.WriteLine("We should have received 4 total messages, we received: " + messages.Count);

                    Console.WriteLine("----------\n");

                    // delete the stream since we are done with it.
                    jsm.DeleteStream(helper.Stream);
                }
            }
            catch (Exception ex)
            {
                helper.ReportException(ex);
            }
        }