private void ChangeOkPull(IJetStream js, ConsumerConfiguration.ConsumerConfigurationBuilder builder) { js.PullSubscribe(SUBJECT, PullSubscribeOptions.Builder().WithConfiguration(builder.Build()).Build()).Unsubscribe(); }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive Expires In", args, Usage) .DefaultStream("fetch-uc-stream") .DefaultSubject("fetch-uc-subject") .DefaultDurable("fetch-uc-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(); // Build our consumer configuration and subscription options. // make sure the ack wait is sufficient to handle the reading and processing of the batch. // Durable is REQUIRED for pull based subscriptions ConsumerConfiguration cc = ConsumerConfiguration.Builder() .WithAckWait(2500) .Build(); PullSubscribeOptions pullOptions = PullSubscribeOptions.Builder() .WithDurable(helper.Durable) // required .WithConfiguration(cc) .Build(); // 0.1 Initialize. subscription // 0.2 Flush outgoing communication with/to the server, useful when app is both JsUtils.Publishing and subscribing. Console.WriteLine("\n----------\n0. Initialize the subscription and pull."); IJetStreamPullSubscription sub = js.PullSubscribe(helper.Subject, pullOptions); c.Flush(1000); // 1. Fetch, but there are no messages yet. // - Read the messages, get them all (0) Console.WriteLine("----------\n1. There are no messages yet"); IList <Msg> messages = sub.Fetch(10, 3000); JsUtils.Report(messages); foreach (Msg m in messages) { m.Ack(); } Console.WriteLine("We should have received 0 total messages, we received: " + messages.Count); // 2. Publish 10 messages // - Fetch messages, get 10 Console.WriteLine("----------\n2. Publish 10 which satisfies the batch"); JsUtils.Publish(js, helper.Subject, "A", 10); messages = sub.Fetch(10, 3000); JsUtils.Report(messages); foreach (Msg m in messages) { m.Ack(); } Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count); // 3. Publish 20 messages // - Fetch messages, only get 10 Console.WriteLine("----------\n3. Publish 20 which is larger than the batch size."); JsUtils.Publish(js, helper.Subject, "B", 20); messages = sub.Fetch(10, 3000); JsUtils.Report(messages); foreach (Msg m in messages) { m.Ack(); } Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count); // 4. There are still messages left from the last // - Fetch messages, get 10 Console.WriteLine("----------\n4. Get the rest of the JsUtils.Publish."); messages = sub.Fetch(10, 3000); JsUtils.Report(messages); foreach (Msg m in messages) { m.Ack(); } Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count); // 5. Publish 5 messages // - Fetch messages, get 5 // - Since there are less than batch size we only get what the server has. Console.WriteLine("----------\n5. Publish 5 which is less than batch size."); JsUtils.Publish(js, helper.Subject, "C", 5); messages = sub.Fetch(10, 3000); JsUtils.Report(messages); foreach (Msg m in messages) { m.Ack(); } Console.WriteLine("We should have received 5 total messages, we received: " + messages.Count); // 6. Publish 15 messages // - Fetch messages, only get 10 Console.WriteLine("----------\n6. Publish 15 which is more than the batch size."); JsUtils.Publish(js, helper.Subject, "D", 15); messages = sub.Fetch(10, 3000); JsUtils.Report(messages); foreach (Msg m in messages) { m.Ack(); } Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count); // 7. There are 5 messages left // - Fetch messages, only get 5 Console.WriteLine("----------\n7. There are 5 messages left."); messages = sub.Fetch(10, 3000); JsUtils.Report(messages); foreach (Msg m in messages) { m.Ack(); } Console.WriteLine("We should have received 5 messages, we received: " + messages.Count); // 8. Read but don't ack. // - Fetch messages, get 10, but either take too long to ack them or don't ack them Console.WriteLine("----------\n8. Fetch but don't ack."); JsUtils.Publish(js, helper.Subject, "E", 10); messages = sub.Fetch(10, 3000); JsUtils.Report(messages); Console.WriteLine("We should have received 10 message, we received: " + messages.Count); Thread.Sleep(3000); // longer than the ackWait // 9. Fetch messages, // - get the 10 messages we didn't ack Console.WriteLine("----------\n9. Fetch, get the messages we did not ack."); messages = sub.Fetch(10, 3000); JsUtils.Report(messages); foreach (Msg m in messages) { m.Ack(); } Console.WriteLine("We should have received 10 message, 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); } }
public void TestConsumerIsNotModified() { Context.RunInJsServer(c => { CreateDefaultTestStream(c); IJetStreamManagement jsm = c.CreateJetStreamManagementContext(); // test with config in issue 105 ConsumerConfiguration cc = ConsumerConfiguration.Builder() .WithDescription("desc") .WithAckPolicy(AckPolicy.Explicit) .WithDeliverPolicy(DeliverPolicy.All) .WithDeliverSubject(Deliver(1)) .WithDeliverGroup(Queue(1)) .WithDurable(Durable(1)) .WithMaxAckPending(65000) .WithMaxDeliver(5) .WithReplayPolicy(ReplayPolicy.Instant) .Build(); jsm.AddOrUpdateConsumer(STREAM, cc); IJetStream js = c.CreateJetStreamContext(); PushSubscribeOptions pushOpts = PushSubscribeOptions.BindTo(STREAM, Durable(1)); js.PushSubscribeSync(SUBJECT, Queue(1), pushOpts); // should not throw an error // testing numerics cc = ConsumerConfiguration.Builder() .WithDeliverPolicy(DeliverPolicy.ByStartSequence) .WithDeliverSubject(Deliver(21)) .WithDurable(Durable(21)) .WithStartSequence(42) .WithMaxDeliver(43) .WithRateLimitBps(44) .WithMaxAckPending(45) .Build(); jsm.AddOrUpdateConsumer(STREAM, cc); pushOpts = PushSubscribeOptions.BindTo(STREAM, Durable(21)); js.PushSubscribeSync(SUBJECT, pushOpts); // should not throw an error cc = ConsumerConfiguration.Builder() .WithDurable(Durable(22)) .WithMaxPullWaiting(46) .Build(); jsm.AddOrUpdateConsumer(STREAM, cc); PullSubscribeOptions pullOpts = PullSubscribeOptions.BindTo(STREAM, Durable(22)); js.PullSubscribe(SUBJECT, pullOpts); // should not throw an error // testing DateTime cc = ConsumerConfiguration.Builder() .WithDeliverPolicy(DeliverPolicy.ByStartTime) .WithDeliverSubject(Deliver(3)) .WithDurable(Durable(3)) .WithStartTime(DateTime.Now.AddHours(1)) .Build(); jsm.AddOrUpdateConsumer(STREAM, cc); pushOpts = PushSubscribeOptions.BindTo(STREAM, Durable(3)); js.PushSubscribeSync(SUBJECT, pushOpts); // should not throw an error // testing boolean and duration cc = ConsumerConfiguration.Builder() .WithDeliverSubject(Deliver(4)) .WithDurable(Durable(4)) .WithFlowControl(1000) .WithHeadersOnly(true) .WithAckWait(2000) .Build(); jsm.AddOrUpdateConsumer(STREAM, cc); pushOpts = PushSubscribeOptions.BindTo(STREAM, Durable(4)); js.PushSubscribeSync(SUBJECT, pushOpts); // should not throw an error // testing enums cc = ConsumerConfiguration.Builder() .WithDeliverSubject(Deliver(5)) .WithDurable(Durable(5)) .WithDeliverPolicy(DeliverPolicy.Last) .WithAckPolicy(AckPolicy.None) .WithReplayPolicy(ReplayPolicy.Original) .Build(); jsm.AddOrUpdateConsumer(STREAM, cc); pushOpts = PushSubscribeOptions.BindTo(STREAM, Durable(5)); js.PushSubscribeSync(SUBJECT, pushOpts); // should not throw an error }); }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive No Wait, Use Cases", args, Usage) .DefaultStream("nowait-uc-stream") .DefaultSubject("nowait-uc-subject") .DefaultDurable("nowait-uc-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 DO NOT start the pull, no wait works differently than regular pull. // With no wait, we have to start the pull the first time and every time the // batch size is exhausted or no waits out. // 0.3 Flush outgoing communication with/to the server, useful when app is both publishing and subscribing. Console.WriteLine("\n----------\n0. Initialize the subscription and pull."); IJetStreamPullSubscription sub = js.PullSubscribe(helper.Subject, pullOptions); c.Flush(1000); // 1. Start the pull, but there are no messages yet. // - Read the messages // - Since there are less than the batch size, we get them all (0) Console.WriteLine("----------\n1. There are no messages yet"); sub.PullNoWait(10); IList <Msg> messages = JsUtils.ReadMessagesAck(sub); Console.WriteLine("We should have received 0 total messages, we received: " + messages.Count); // 2. Publish 10 messages // - Start the pull // - Read the messages // - Since there are exactly the batch size we get them all Console.WriteLine("----------\n2. Publish 10 which satisfies the batch"); JsUtils.Publish(js, helper.Subject, "A", 10); sub.PullNoWait(10); messages = JsUtils.ReadMessagesAck(sub); Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count); // 3. Publish 20 messages // - Start the pull // - Read the messages Console.WriteLine("----------\n3. Publish 20 which is larger than the batch size."); JsUtils.Publish(js, helper.Subject, "B", 20); sub.PullNoWait(10); messages = JsUtils.ReadMessagesAck(sub); Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count); // 4. There are still messages left from the last // - Start the pull // - Read the messages Console.WriteLine("----------\n4. Get the rest of the publish."); sub.PullNoWait(10); messages = JsUtils.ReadMessagesAck(sub); Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count); // 5. Publish 5 messages // - Start the pull // - Read the messages Console.WriteLine("----------\n5. Publish 5 which is less than batch size."); JsUtils.Publish(js, helper.Subject, "C", 5); sub.PullNoWait(10); messages = JsUtils.ReadMessagesAck(sub); Console.WriteLine("We should have received 5 total messages, we received: " + messages.Count); // 6. Publish 14 messages // - Start the pull // - Read the messages // - we do NOT get a nowait status message if there are more or equals messages than the batch Console.WriteLine("----------\n6. Publish 14 which is more than the batch size."); JsUtils.Publish(js, helper.Subject, "D", 14); sub.PullNoWait(10); messages = JsUtils.ReadMessagesAck(sub); Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count); // 7. There are 4 messages left // - Start the pull // - Read the messages // - Since there are less than batch size the last message we get will be a status 404 message. Console.WriteLine("----------\n7. There are 4 messages left, which is less than the batch size."); sub.PullNoWait(10); messages = JsUtils.ReadMessagesAck(sub); Console.WriteLine("We should have received 4 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); } }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive Expires In, Use Cases", args, Usage) .DefaultStream("expires-in-uc-stream") .DefaultSubject("expires-in-uc-subject") .DefaultDurable("expires-in-uc-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); // 1. Publish some that is less than the batch size. Console.WriteLine("\n----------\n1. Publish some amount of messages, but not entire batch size."); JsUtils.Publish(js, helper.Subject, "A", 6); sub.PullExpiresIn(10, 1200); IList <Msg> messages = JsUtils.ReadMessagesAck(sub, timeout: 2000); Console.WriteLine("We should have received 6 total messages, we received: " + messages.Count); // 2. Publish some more covering our pull size... Console.WriteLine("----------\n2. Publish more than the batch size."); sub.PullExpiresIn(10, 1200); JsUtils.Publish(js, helper.Subject, "B", 14); messages = JsUtils.ReadMessagesAck(sub, timeout: 2000); Console.WriteLine("We should have received 10 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 issuing a pull."); messages = JsUtils.ReadMessagesAck(sub, timeout: 2000); 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. Issue the pull to get the last 4."); sub.PullExpiresIn(10, 1200); messages = JsUtils.ReadMessagesAck(sub, timeout: 2000); Console.WriteLine("We should have received 4 total messages, we received: " + messages.Count); // 5. publish a lot of messages Console.WriteLine("----------\n5. Publish a lot of messages. The last pull was under the batch size."); Console.WriteLine(" Issue another pull with batch size less than number of messages."); JsUtils.Publish(js, helper.Subject, "C", 25); sub.PullExpiresIn(10, 1200); messages = JsUtils.ReadMessagesAck(sub, timeout: 2000); Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count); // 6. there are still more messages Console.WriteLine("----------\n6. Still more messages. Issue another pull with batch size less than number of messages."); sub.PullExpiresIn(10, 1200); messages = JsUtils.ReadMessagesAck(sub, timeout: 2000); Console.WriteLine("We should have received 10 total messages, we received: " + messages.Count); // 7. there are still more messages Console.WriteLine("----------\n7. Still more messages. Issue another pull with batch size more than number of messages."); sub.PullExpiresIn(10, 1200); messages = JsUtils.ReadMessagesAck(sub, timeout: 2000); Console.WriteLine("We should have received 5 total messages, we received: " + messages.Count); // 8. we got them all Console.WriteLine("----------\n8. No messages left."); sub.PullExpiresIn(10, 1200); messages = JsUtils.ReadMessagesAck(sub, timeout: 2000); Console.WriteLine("We should have received 0 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); } }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("Pull Subscription using primitive Expires In", args, Usage) .DefaultStream("expires-in-stream") .DefaultSubject("expires-in-subject") .DefaultDurable("expires-in-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, "expires-in-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.PullExpiresIn(10, 1000); 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); } }
public void TestFetch() { Console.SetOut(new ConsoleWriter(output)); Context.RunInJsServer(c => { // create the stream. CreateDefaultTestStream(c); // Create our JetStream context. IJetStream js = c.CreateJetStreamContext(); int fetchMs = 3000; int ackWaitMs = fetchMs * 2; ConsumerConfiguration cc = ConsumerConfiguration.Builder() .WithAckWait(ackWaitMs) .Build(); PullSubscribeOptions options = PullSubscribeOptions.Builder() .WithDurable(DURABLE) .WithConfiguration(cc) .Build(); IJetStreamPullSubscription sub = js.PullSubscribe(SUBJECT, options); AssertSubscription(sub, STREAM, DURABLE, null, true); c.Flush(DefaultTimeout); // flush outgoing communication with/to the server IList <Msg> messages = sub.Fetch(10, fetchMs); ValidateRead(0, messages.Count); AckAll(messages); Thread.Sleep(ackWaitMs); // let the pull expire JsPublish(js, SUBJECT, "A", 10); messages = sub.Fetch(10, fetchMs); ValidateRead(10, messages.Count); AckAll(messages); JsPublish(js, SUBJECT, "B", 20); messages = sub.Fetch(10, fetchMs); ValidateRead(10, messages.Count); AckAll(messages); messages = sub.Fetch(10, fetchMs); ValidateRead(10, messages.Count); AckAll(messages); JsPublish(js, SUBJECT, "C", 5); messages = sub.Fetch(10, fetchMs); ValidateRead(5, messages.Count); AckAll(messages); Thread.Sleep(fetchMs * 2); // let the pull expire JsPublish(js, SUBJECT, "D", 15); messages = sub.Fetch(10, fetchMs); ValidateRead(10, messages.Count); AckAll(messages); messages = sub.Fetch(10, fetchMs); ValidateRead(5, messages.Count); AckAll(messages); JsPublish(js, SUBJECT, "E", 10); messages = sub.Fetch(10, fetchMs); ValidateRead(10, messages.Count); Thread.Sleep(ackWaitMs); messages = sub.Fetch(10, fetchMs); ValidateRead(10, messages.Count); AckAll(messages); }); }
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 }); }
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); }); }
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); } }