private static void PubSync(Context ctx, IConnection c, Stats stats, int id) { IJetStream js = c.CreateJetStreamContext(); if (ctx.LatencyFlag) { _pub(ctx, stats, id, (s, p) => js.Publish(BuildLatencyMessage(s, p))); } else { _pub(ctx, stats, id, (s, p) => js.Publish(s, p)); } }
public static void JsPublish(IJetStream js, string subject, int startId, int count) { for (int x = 0; x < count; x++) { js.Publish(new Msg(subject, DataBytes(startId++))); } }
public void TestPublishNoAck() { Context.RunInJsServer(c => { CreateDefaultTestStream(c); JetStreamOptions jso = JetStreamOptions.Builder().WithPublishNoAck(true).Build(); IJetStream js = c.CreateJetStreamContext(jso); string data1 = "noackdata1"; string data2 = "noackdata2"; PublishAck pa = js.Publish(SUBJECT, Encoding.ASCII.GetBytes(data1)); Assert.Null(pa); Task <PublishAck> task = js.PublishAsync(SUBJECT, Encoding.ASCII.GetBytes(data2)); Assert.Null(task.Result); IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(SUBJECT); Msg m = sub.NextMessage(DefaultTimeout); Assert.NotNull(m); Assert.Equal(data1, Encoding.ASCII.GetString(m.Data)); m = sub.NextMessage(DefaultTimeout); Assert.NotNull(m); Assert.Equal(data2, Encoding.ASCII.GetString(m.Data)); }); }
public void Run() { for (int x = 1; x <= msgCount; x++) { js.Publish(SUBJECT, Encoding.ASCII.GetBytes("Data # " + x)); } }
public void TestPublishVarieties() { Context.RunInJsServer(c => { CreateDefaultTestStream(c); IJetStream js = c.CreateJetStreamContext(); PublishAck pa = js.Publish(SUBJECT, DataBytes(1)); AssertPublishAck(pa, 1); Msg msg = new Msg(SUBJECT, DataBytes(2)); pa = js.Publish(msg); AssertPublishAck(pa, 2); PublishOptions po = PublishOptions.Builder().Build(); pa = js.Publish(SUBJECT, DataBytes(3), po); AssertPublishAck(pa, 3); msg = new Msg(SUBJECT, DataBytes(4)); pa = js.Publish(msg, po); AssertPublishAck(pa, 4); pa = js.Publish(SUBJECT, null); AssertPublishAck(pa, 5); msg = new Msg(SUBJECT); pa = js.Publish(msg); AssertPublishAck(pa, 6); pa = js.Publish(SUBJECT, null, po); AssertPublishAck(pa, 7); msg = new Msg(SUBJECT); pa = js.Publish(msg, po); AssertPublishAck(pa, 8); IJetStreamPushSyncSubscription s = js.PushSubscribeSync(SUBJECT); AssertNextMessage(s, Data(1)); AssertNextMessage(s, Data(2)); AssertNextMessage(s, Data(3)); AssertNextMessage(s, Data(4)); AssertNextMessage(s, null); // 5 AssertNextMessage(s, null); // 6 AssertNextMessage(s, null); // 7 AssertNextMessage(s, null); // 8 // bad subject Assert.Throws <NATSNoRespondersException>(() => js.Publish(Subject(999), null)); }); }
public static void JsPublish(IJetStream js, string subject, string prefix, int startId, int count) { int end = startId + count - 1; for (int x = startId; x <= end; x++) { string data = prefix + x; js.Publish(new Msg(subject, Encoding.ASCII.GetBytes(data))); } }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("JetStream Publish Vs Core Publish", args, Usage) .DefaultStream("js-or-core-stream") .DefaultSubject("js-or-core-subject") .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 a JetStream context IJetStream js = c.CreateJetStreamContext(); // Regular Nats publish is straightforward c.Publish(helper.Subject, Encoding.ASCII.GetBytes("regular-message")); // A JetStream publish allows you to set publish options // that a regular publish does not. // A JetStream publish returns an ack of the publish. There // is no ack in a regular message. Msg msg = new Msg(helper.Subject, Encoding.ASCII.GetBytes("js-message")); PublishAck pa = js.Publish(msg); Console.WriteLine(pa); // set up the subscription IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(helper.Subject); c.Flush(500); // flush outgoing communication with/to the server // Both messages appear in the stream as JetStream messages msg = sub.NextMessage(500); msg.Ack(); Console.WriteLine("Received Data: '" + Encoding.ASCII.GetString(msg.Data) + "'\n Meta: " + msg.MetaData); msg = sub.NextMessage(500); msg.Ack(); Console.WriteLine("Received Data: '" + Encoding.ASCII.GetString(msg.Data) + "'\n Meta: " + msg.MetaData); // delete the stream since we are done with it. jsm.DeleteStream(helper.Stream); } } catch (Exception ex) { helper.ReportException(ex); } }
public void TestPushSyncFlowControl() { InterlockedInt fcps = new InterlockedInt(); Action <Options> optionsModifier = opts => { opts.FlowControlProcessedEventHandler = (sender, args) => { fcps.Increment(); }; }; Context.RunInJsServer(new TestServerInfo(TestSeedPorts.AutoPort.Increment()), optionsModifier, c => { // create the stream. CreateDefaultTestStream(c); // Create our JetStream context. IJetStream js = c.CreateJetStreamContext(); byte[] data = new byte[8192]; int MSG_COUNT = 1000; for (int x = 100_000; x < MSG_COUNT + 100_000; x++) { byte[] fill = Encoding.ASCII.GetBytes("" + x); Array.Copy(fill, 0, data, 0, 6); js.Publish(new Msg(SUBJECT, data)); } InterlockedInt count = new InterlockedInt(); HashSet <string> set = new HashSet <string>(); ConsumerConfiguration cc = ConsumerConfiguration.Builder().WithFlowControl(1000).Build(); PushSubscribeOptions pso = PushSubscribeOptions.Builder().WithConfiguration(cc).Build(); IJetStreamPushSyncSubscription ssub = js.PushSubscribeSync(SUBJECT, pso); for (int x = 0; x < MSG_COUNT; x++) { Msg msg = ssub.NextMessage(1000); byte[] fill = new byte[6]; Array.Copy(msg.Data, 0, fill, 0, 6); string id = Encoding.ASCII.GetString(fill); if (set.Add(id)) { count.Increment(); } msg.Ack(); } Assert.Equal(MSG_COUNT, count.Read()); Assert.True(fcps.Read() > 0); }); }
public void TestGetAndDeleteMessage() { Context.RunInJsServer(c => { CreateDefaultTestStream(c); IJetStream js = c.CreateJetStreamContext(); MsgHeader h = new MsgHeader(); h.Add("foo", "bar"); DateTime beforeCreated = DateTime.Now; js.Publish(new Msg(SUBJECT, null, h, DataBytes(1))); js.Publish(new Msg(SUBJECT, null)); IJetStreamManagement jsm = c.CreateJetStreamManagementContext(); MessageInfo mi = jsm.GetMessage(STREAM, 1); Assert.Equal(SUBJECT, mi.Subject); Assert.Equal(Data(1), System.Text.Encoding.ASCII.GetString(mi.Data)); Assert.Equal(1U, mi.Sequence); Assert.True(mi.Time >= beforeCreated); Assert.NotNull(mi.Headers); Assert.Equal("bar", mi.Headers["foo"]); mi = jsm.GetMessage(STREAM, 2); Assert.Equal(SUBJECT, mi.Subject); Assert.Null(mi.Data); Assert.Equal(2U, mi.Sequence); Assert.True(mi.Time >= beforeCreated); Assert.Null(mi.Headers); Assert.True(jsm.DeleteMessage(STREAM, 1)); Assert.Throws <NATSJetStreamException>(() => jsm.DeleteMessage(STREAM, 1)); Assert.Throws <NATSJetStreamException>(() => jsm.GetMessage(STREAM, 1)); Assert.Throws <NATSJetStreamException>(() => jsm.GetMessage(STREAM, 3)); Assert.Throws <NATSJetStreamException>(() => jsm.DeleteMessage(Stream(999), 1)); Assert.Throws <NATSJetStreamException>(() => jsm.GetMessage(Stream(999), 1)); }); }
public void TestPublishMiscExceptions() { Context.RunInJsServer(c => { CreateDefaultTestStream(c); IJetStream js = c.CreateJetStreamContext(); // stream supplied and matches PublishOptions po = PublishOptions.Builder() .WithStream(STREAM) .Build(); js.Publish(SUBJECT, DataBytes(999), po); // mismatch stream to PO stream po = PublishOptions.Builder() .WithStream(Stream(999)) .Build(); Assert.Throws <NATSJetStreamException>(() => js.Publish(SUBJECT, DataBytes(999), po)); // invalid subject Assert.Throws <NATSNoRespondersException>(() => js.Publish(Subject(999), DataBytes(999))); }); }
public static void PublishInBackground(IJetStream js, String subject, String prefix, int count) { new Thread(() => { try { for (int x = 1; x <= count; x++) { js.Publish(subject, Encoding.ASCII.GetBytes(prefix + "-" + x)); } } catch (Exception e) { Console.WriteLine(e); Environment.Exit(-1); } }).Start(); Thread.Sleep(100); // give the publish thread a little time to get going }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("JetStream Publish", args, Usage) .DefaultStream("example-stream") .DefaultSubject("example-subject") .DefaultPayload("Hello") .DefaultCount(10) .Build(); try { using (IConnection c = new ConnectionFactory().CreateConnection(helper.MakeOptions())) { // Use the utility to create a stream stored in memory. JsUtils.CreateStreamOrUpdateSubjects(c, helper.Stream, helper.Subject); // create a JetStream context IJetStream js = c.CreateJetStreamContext(); int stop = helper.Count < 2 ? 2 : helper.Count + 1; for (int x = 1; x < stop; x++) { // make unique message data if you want more than 1 message byte[] data = helper.Count < 2 ? Encoding.UTF8.GetBytes(helper.Payload) : Encoding.UTF8.GetBytes(helper.Payload + "-" + x); // Publish a message and print the results of the publish acknowledgement. Msg msg = new Msg(helper.Subject, null, helper.Header, data); // We'll use the defaults for this simple example, but there are options // to constrain publishing to certain streams, expect sequence numbers and // more. See the JetStreamPublishWithOptionsUseCases example for details. // An exception will be thrown if there is a failure. PublishAck pa = js.Publish(msg); Console.WriteLine("Published message '{0}' on subject '{1}', stream '{2}', seqno '{3}'.", Encoding.UTF8.GetString(data), helper.Subject, pa.Stream, pa.Seq); } } } catch (Exception ex) { helper.ReportException(ex); } }
public static void Publish(IJetStream js, String subject, String prefix, int count, bool verbose = true) { if (verbose) { Console.Write("Publish ->"); } for (int x = 1; x <= count; x++) { String data = prefix + x; if (verbose) { Console.Write(" " + data); } js.Publish(subject, Encoding.UTF8.GetBytes(data)); } if (verbose) { Console.WriteLine(" <-"); } }
public void TestMessageWithHeadersOnly() { Context.RunInJsServer(c => { // create the stream. CreateDefaultTestStream(c); // Create our JetStream context. IJetStream js = c.CreateJetStreamContext(); MsgHeader h = new MsgHeader(); h["foo"] = "bar"; js.Publish(new Msg(SUBJECT, h, DataBytes(1))); // Build our subscription options. PushSubscribeOptions options = ConsumerConfiguration.Builder() .WithHeadersOnly(true).BuildPushSubscribeOptions(); IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(SUBJECT, options); c.Flush(DefaultTimeout); // flush outgoing communication with/to the server Msg m = sub.NextMessage(1000); Assert.Empty(m.Data); Assert.True(m.HasHeaders); Assert.Equal("bar", m.Header["foo"]); Assert.Equal("6", m.Header[JetStreamConstants.MsgSizeHeader]); sub.Unsubscribe(); // without headers only sub = js.PushSubscribeSync(SUBJECT); c.Flush(DefaultTimeout); // flush outgoing communication with/to the server m = sub.NextMessage(1000); Assert.Equal(6, m.Data.Length); Assert.True(m.HasHeaders); Assert.Equal("bar", m.Header["foo"]); Assert.Null(m.Header[JetStreamConstants.MsgSizeHeader]); }); }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("NATS JetStream Push Subscribe Queue Durable", args, Usage) .DefaultStream("qdur-stream") .DefaultSubject("qdur-subject") .DefaultQueue("qdur-queue") .DefaultDurable("qdur-durable") .DefaultDeliverSubject("qdur-deliver") .DefaultCount(100) .DefaultSubsCount(5) .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); IJetStream js = c.CreateJetStreamContext(); Console.WriteLine(); // create the consumer ahead of time ConsumerConfiguration cc = ConsumerConfiguration.Builder() .WithDurable(helper.Durable) .WithDeliverSubject(helper.DeliverSubject) .WithDeliverGroup(helper.Queue) .Build(); jsm.AddOrUpdateConsumer(helper.Stream, cc); // we will just bind to that consumer PushSubscribeOptions pso = PushSubscribeOptions.BindTo(helper.Stream, helper.Durable); InterlockedLong allReceived = new InterlockedLong(); IList <JsQueueSubscriber> subscribers = new List <JsQueueSubscriber>(); IList <Thread> subThreads = new List <Thread>(); for (int id = 1; id <= helper.SubsCount; id++) { // setup the subscription IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(helper.Subject, helper.Queue, pso); // create and track the runnable JsQueueSubscriber qs = new JsQueueSubscriber(id, 100, js, sub, allReceived); subscribers.Add(qs); // create, track and start the thread Thread t = new Thread(qs.Run); subThreads.Add(t); t.Start(); } c.Flush(500); // flush outgoing communication with/to the server // create and start the publishing Thread pubThread = new Thread(() => { for (int x = 1; x <= helper.Count; x++) { js.Publish(helper.Subject, Encoding.ASCII.GetBytes("Data # " + x)); } }); pubThread.Start(); // wait for all threads to finish pubThread.Join(10000); foreach (Thread t in subThreads) { t.Join(10000); } foreach (JsQueueSubscriber qs in subscribers) { qs.Report(); } Console.WriteLine(); // delete the stream since we are done with it. jsm.DeleteStream(helper.Stream); } } catch (Exception ex) { helper.ReportException(ex); } }
public void TestDeliveryPolicy() { Context.RunInJsServer(c => { IJetStreamManagement jsm = c.CreateJetStreamManagementContext(); IJetStream js = c.CreateJetStreamContext(); CreateMemoryStream(jsm, STREAM, SUBJECT_STAR); string subjectA = SubjectDot("A"); string subjectB = SubjectDot("B"); js.Publish(subjectA, DataBytes(1)); js.Publish(subjectA, DataBytes(2)); Thread.Sleep(1500); js.Publish(subjectA, DataBytes(3)); js.Publish(subjectB, DataBytes(91)); js.Publish(subjectB, DataBytes(92)); // DeliverPolicy.All PushSubscribeOptions pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverPolicy(DeliverPolicy.All).Build()) .Build(); IJetStreamPushSyncSubscription sub = js.PushSubscribeSync(subjectA, pso); Msg m1 = sub.NextMessage(1000); AssertMessage(m1, 1); Msg m2 = sub.NextMessage(1000); AssertMessage(m2, 2); Msg m3 = sub.NextMessage(1000); AssertMessage(m3, 3); // DeliverPolicy.Last pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverPolicy(DeliverPolicy.Last).Build()) .Build(); sub = js.PushSubscribeSync(subjectA, pso); Msg m = sub.NextMessage(1000); AssertMessage(m, 3); AssertNoMoreMessages(sub); // DeliverPolicy.New - No new messages between subscribe and next message pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder().WithDeliverPolicy(DeliverPolicy.New).Build()) .Build(); sub = js.PushSubscribeSync(subjectA, pso); AssertNoMoreMessages(sub); // DeliverPolicy.New - New message between subscribe and next message sub = js.PushSubscribeSync(subjectA, pso); js.Publish(subjectA, DataBytes(4)); m = sub.NextMessage(1000); AssertMessage(m, 4); // DeliverPolicy.ByStartSequence pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder() .WithDeliverPolicy(DeliverPolicy.ByStartSequence) .WithStartSequence(3) .Build()) .Build(); sub = js.PushSubscribeSync(subjectA, pso); m = sub.NextMessage(1000); AssertMessage(m, 3); m = sub.NextMessage(1000); AssertMessage(m, 4); // DeliverPolicy.ByStartTime pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder() .WithDeliverPolicy(DeliverPolicy.ByStartTime) .WithStartTime(m3.MetaData.Timestamp.AddSeconds(-1)) .Build()) .Build(); sub = js.PushSubscribeSync(subjectA, pso); m = sub.NextMessage(1000); AssertMessage(m, 3); m = sub.NextMessage(1000); AssertMessage(m, 4); // DeliverPolicy.LastPerSubject pso = PushSubscribeOptions.Builder() .WithConfiguration(ConsumerConfiguration.Builder() .WithDeliverPolicy(DeliverPolicy.LastPerSubject) .WithFilterSubject(subjectA) .Build()) .Build(); sub = js.PushSubscribeSync(subjectA, pso); m = sub.NextMessage(1000); AssertMessage(m, 4); // DeliverPolicy.ByStartSequence with a deleted record PublishAck pa4 = js.Publish(subjectA, DataBytes(4)); PublishAck pa5 = js.Publish(subjectA, DataBytes(5)); js.Publish(subjectA, DataBytes(6)); jsm.DeleteMessage(STREAM, pa4.Seq); jsm.DeleteMessage(STREAM, pa5.Seq); pso = ConsumerConfiguration.Builder() .WithDeliverPolicy(DeliverPolicy.ByStartSequence) .WithStartSequence(pa4.Seq) .BuildPushSubscribeOptions(); sub = js.PushSubscribeSync(subjectA, pso); m = sub.NextMessage(1000); AssertMessage(m, 6); }); }
public static PublishAck JsPublish(IJetStream js, string subject, string data) { return(js.Publish(new Msg(subject, Encoding.ASCII.GetBytes(data)))); }
public static PublishAck JsPublish(IJetStream js) { return(js.Publish(new Msg(SUBJECT, DataBytes()))); }
public static void Main(string[] args) { ArgumentHelper helper = new ArgumentHelperBuilder("JetStream Publish With Options Use Cases", args, Usage) .DefaultStream("pubopts-stream") .DefaultSubject("pubopts-subject") .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); // get a regular context IJetStream js = c.CreateJetStreamContext(); PublishOptions.PublishOptionsBuilder builder = PublishOptions.Builder() .WithExpectedStream(helper.Stream) .WithMessageId("mid1"); PublishAck pa = js.Publish(helper.Subject, Encoding.ASCII.GetBytes("message1"), builder.Build()); Console.WriteLine("Published message on subject {0}, stream {1}, seqno {2}.", helper.Subject, pa.Stream, pa.Seq); // IMPORTANT! // You can reuse the builder in 2 ways. // 1. Manually set a field to null or to DefaultLastSequence if you want to clear it out. // 2. Use the clearExpected method to clear the expectedLastId, expectedLastSequence and messageId fields // Manual re-use 1. Clearing some fields builder .WithExpectedLastMsgId("mid1") .WithExpectedLastSequence(PublishOptions.DefaultLastSequence) .WithMessageId(null); pa = js.Publish(helper.Subject, Encoding.ASCII.GetBytes("message2"), builder.Build()); Console.WriteLine("Published message on subject {0}, stream {1}, seqno {2}.", helper.Subject, pa.Stream, pa.Seq); // Manual re-use 2. Setting all the expected fields again builder .WithExpectedLastMsgId(null) .WithExpectedLastSequence(PublishOptions.DefaultLastSequence) .WithMessageId("mid3"); pa = js.Publish(helper.Subject, Encoding.ASCII.GetBytes("message3"), builder.Build()); Console.WriteLine("Published message on subject {0}, stream {1}, seqno {2}.", helper.Subject, pa.Stream, pa.Seq); // reuse() method clears all the fields, then we set some fields. builder.ClearExpected() .WithExpectedLastSequence(pa.Seq) .WithMessageId("mid4"); pa = js.Publish(helper.Subject, Encoding.ASCII.GetBytes("message4"), builder.Build()); Console.WriteLine("Published message on subject {0}, stream {1}, seqno {2}.", helper.Subject, pa.Stream, pa.Seq); // exception when the expected stream does not match [10060] try { PublishOptions errOpts = PublishOptions.Builder().WithExpectedStream("wrongStream").Build(); js.Publish(helper.Subject, Encoding.ASCII.GetBytes("ex1"), errOpts); } catch (NATSJetStreamException e) { Console.WriteLine($"Exception was: '{e.ErrorDescription}'"); } // exception with wrong last msg ID [10070] try { PublishOptions errOpts = PublishOptions.Builder().WithExpectedLastMsgId("wrongId").Build(); js.Publish(helper.Subject, Encoding.ASCII.GetBytes("ex2"), errOpts); } catch (NATSJetStreamException e) { Console.WriteLine($"Exception was: '{e.ErrorDescription}'"); } // exception with wrong last sequence wrong last sequence: 4 [10071] try { PublishOptions errOpts = PublishOptions.Builder().WithExpectedLastSequence(999).Build(); js.Publish(helper.Subject, Encoding.ASCII.GetBytes("ex3"), errOpts); } catch (NATSJetStreamException e) { Console.WriteLine($"Exception was: '{e.ErrorDescription}'"); } // delete the stream since we are done with it. jsm.DeleteStream(helper.Stream); } } catch (Exception ex) { helper.ReportException(ex); } }
public void TestPublishExpectations() { Context.RunInJsServer(c => { CreateMemoryStream(c, STREAM, Subject(1), Subject(2)); IJetStream js = c.CreateJetStreamContext(); PublishOptions po = PublishOptions.Builder() .WithExpectedStream(STREAM) .WithMessageId(MessageId(1)) .Build(); PublishAck pa = js.Publish(Subject(1), DataBytes(1), po); AssertPublishAck(pa, 1); po = PublishOptions.Builder() .WithExpectedLastMsgId(MessageId(1)) .WithMessageId(MessageId(2)) .Build(); pa = js.Publish(Subject(1), DataBytes(2), po); AssertPublishAck(pa, 2); po = PublishOptions.Builder() .WithExpectedLastSequence(2) .WithMessageId(MessageId(3)) .Build(); pa = js.Publish(Subject(1), DataBytes(3), po); AssertPublishAck(pa, 3); po = PublishOptions.Builder() .WithExpectedLastSequence(3) .WithMessageId(MessageId(4)) .Build(); pa = js.Publish(Subject(2), DataBytes(4), po); AssertPublishAck(pa, 4); po = PublishOptions.Builder() .WithExpectedLastSubjectSequence(3) .WithMessageId(MessageId(5)) .Build(); pa = js.Publish(Subject(1), DataBytes(5), po); AssertPublishAck(pa, 5); po = PublishOptions.Builder() .WithExpectedLastSubjectSequence(4) .WithMessageId(MessageId(6)) .Build(); pa = js.Publish(Subject(2), DataBytes(6), po); AssertPublishAck(pa, 6); PublishOptions po1 = PublishOptions.Builder().WithExpectedStream(Stream(999)).Build(); Assert.Throws <NATSJetStreamException>(() => js.Publish(Subject(1), DataBytes(999), po1)); PublishOptions po2 = PublishOptions.Builder().WithExpectedLastMsgId(MessageId(999)).Build(); Assert.Throws <NATSJetStreamException>(() => js.Publish(Subject(1), DataBytes(999), po2)); PublishOptions po3 = PublishOptions.Builder().WithExpectedLastSequence(999).Build(); Assert.Throws <NATSJetStreamException>(() => js.Publish(Subject(1), DataBytes(999), po3)); PublishOptions po4 = PublishOptions.Builder().WithExpectedLastSubjectSequence(999).Build(); Assert.Throws <NATSJetStreamException>(() => js.Publish(Subject(1), DataBytes(999), po4)); }); }
public void TestPushAsyncFlowControl() { InterlockedInt fcps = new InterlockedInt(); Action <Options> optionsModifier = opts => { opts.FlowControlProcessedEventHandler = (sender, args) => { fcps.Increment(); }; }; Context.RunInJsServer(new TestServerInfo(TestSeedPorts.AutoPort.Increment()), optionsModifier, c => { // create the stream. CreateDefaultTestStream(c); // Create our JetStream context. IJetStream js = c.CreateJetStreamContext(); byte[] data = new byte[8192]; int msgCount = 1000; for (int x = 100_000; x < msgCount + 100_000; x++) { byte[] fill = Encoding.ASCII.GetBytes("" + x); Array.Copy(fill, 0, data, 0, 6); js.Publish(new Msg(SUBJECT, data)); } InterlockedInt count = new InterlockedInt(); HashSet <string> set = new HashSet <string>(); CountdownEvent latch = new CountdownEvent(msgCount); // create our message handler, does not ack void Handler(object sender, MsgHandlerEventArgs args) { byte[] fill = new byte[6]; Array.Copy(args.Message.Data, 0, fill, 0, 6); string id = Encoding.ASCII.GetString(fill); if (set.Add(id)) { count.Increment(); } args.Message.Ack(); latch.Signal(); } // subscribe using the handler ConsumerConfiguration cc = ConsumerConfiguration.Builder().WithFlowControl(1000).Build(); PushSubscribeOptions pso = PushSubscribeOptions.Builder().WithConfiguration(cc).Build(); js.PushSubscribeAsync(SUBJECT, Handler, false, pso); // wait for messages to arrive using the countdown latch. latch.Wait(); Assert.Equal(msgCount, count.Read()); Assert.True(fcps.Read() > 0); }); }