Skip to content

Commit

Permalink
More dotnet2 examples (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
mtmk authored Dec 5, 2023
1 parent b2893a4 commit 748d38a
Show file tree
Hide file tree
Showing 59 changed files with 2,682 additions and 57 deletions.
2 changes: 1 addition & 1 deletion docker/dotnet2/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM mcr.microsoft.com/dotnet/sdk:6.0
FROM mcr.microsoft.com/dotnet/sdk:8.0

WORKDIR /src

Expand Down
13 changes: 0 additions & 13 deletions docker/dotnet2/example.csproj

This file was deleted.

105 changes: 105 additions & 0 deletions dotnet2.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "messaging-pub-sub", "examples\messaging\pub-sub\dotnet2\messaging-pub-sub.csproj", "{B8E154A8-79C7-403B-949B-83E084ED4B9D}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docker", "docker", "{738E884F-DB8E-4F45-8B7E-D018C1384A0C}"
ProjectSection(SolutionItems) = preProject
docker\dotnet2\Dockerfile = docker\dotnet2\Dockerfile
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "messaging-protobuf", "examples\messaging\protobuf\dotnet2\messaging-protobuf.csproj", "{C94CC882-87D1-4155-A03A-82CE03FB4B36}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "messaging-concurrent", "examples\messaging\concurrent\dotnet2\messaging-concurrent.csproj", "{18393E5C-2816-42AF-9EEF-C9B761D20A53}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "messaging-iterating-multiple-subscriptions", "examples\messaging\iterating-multiple-subscriptions\dotnet2\messaging-iterating-multiple-subscriptions.csproj", "{39A3C1EA-903C-49FB-B732-2840DE482204}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "messaging-json", "examples\messaging\json\dotnet2\messaging-json.csproj", "{FE8671EC-CC41-4BD9-8EFB-38C1D417AC58}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "messaging-request-reply", "examples\messaging\request-reply\dotnet2\messaging-request-reply.csproj", "{AEF65329-7E66-46A3-8789-078F89954543}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "jetstream-limits-stream", "examples\jetstream\limits-stream\dotnet2\jetstream-limits-stream.csproj", "{EDDBAF02-74D2-463A-9A9D-2F570D7EDAD0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "jetstream-interest-stream", "examples\jetstream\interest-stream\dotnet2\jetstream-interest-stream.csproj", "{D93AE1C6-8AC0-48A3-A023-EDB3A7E6055D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "jetstream-workqueue-stream", "examples\jetstream\workqueue-stream\dotnet2\jetstream-workqueue-stream.csproj", "{C3CEAB63-E841-4585-BFF7-3A4BF9F78BE9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "jetstream-pull-consumer", "examples\jetstream\pull-consumer\dotnet2\jetstream-pull-consumer.csproj", "{7671C02D-9D21-4124-97DE-80EB55879377}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "jetstream-pull-consumer-limits", "examples\jetstream\pull-consumer-limits\dotnet2\jetstream-pull-consumer-limits.csproj", "{F70CB8D4-71C1-466A-AEF9-91F4DD37988C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "kv-intro", "examples\kv\intro\dotnet2\kv-intro.csproj", "{CFD0ECE5-7675-45D6-AFEA-532983C6D1FA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "os-intro", "examples\os\intro\dotnet2\os-intro.csproj", "{08EEA81C-62AF-464E-96A2-8F514B37CBE0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "services-intro", "examples\services\intro\dotnet2\services-intro.csproj", "{88CDA1EE-8CFF-4123-86F7-6FAE12CF01F9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B8E154A8-79C7-403B-949B-83E084ED4B9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B8E154A8-79C7-403B-949B-83E084ED4B9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8E154A8-79C7-403B-949B-83E084ED4B9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8E154A8-79C7-403B-949B-83E084ED4B9D}.Release|Any CPU.Build.0 = Release|Any CPU
{C94CC882-87D1-4155-A03A-82CE03FB4B36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C94CC882-87D1-4155-A03A-82CE03FB4B36}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C94CC882-87D1-4155-A03A-82CE03FB4B36}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C94CC882-87D1-4155-A03A-82CE03FB4B36}.Release|Any CPU.Build.0 = Release|Any CPU
{18393E5C-2816-42AF-9EEF-C9B761D20A53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18393E5C-2816-42AF-9EEF-C9B761D20A53}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18393E5C-2816-42AF-9EEF-C9B761D20A53}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18393E5C-2816-42AF-9EEF-C9B761D20A53}.Release|Any CPU.Build.0 = Release|Any CPU
{39A3C1EA-903C-49FB-B732-2840DE482204}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{39A3C1EA-903C-49FB-B732-2840DE482204}.Debug|Any CPU.Build.0 = Debug|Any CPU
{39A3C1EA-903C-49FB-B732-2840DE482204}.Release|Any CPU.ActiveCfg = Release|Any CPU
{39A3C1EA-903C-49FB-B732-2840DE482204}.Release|Any CPU.Build.0 = Release|Any CPU
{FE8671EC-CC41-4BD9-8EFB-38C1D417AC58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FE8671EC-CC41-4BD9-8EFB-38C1D417AC58}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FE8671EC-CC41-4BD9-8EFB-38C1D417AC58}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FE8671EC-CC41-4BD9-8EFB-38C1D417AC58}.Release|Any CPU.Build.0 = Release|Any CPU
{AEF65329-7E66-46A3-8789-078F89954543}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AEF65329-7E66-46A3-8789-078F89954543}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AEF65329-7E66-46A3-8789-078F89954543}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AEF65329-7E66-46A3-8789-078F89954543}.Release|Any CPU.Build.0 = Release|Any CPU
{EDDBAF02-74D2-463A-9A9D-2F570D7EDAD0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EDDBAF02-74D2-463A-9A9D-2F570D7EDAD0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EDDBAF02-74D2-463A-9A9D-2F570D7EDAD0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EDDBAF02-74D2-463A-9A9D-2F570D7EDAD0}.Release|Any CPU.Build.0 = Release|Any CPU
{D93AE1C6-8AC0-48A3-A023-EDB3A7E6055D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D93AE1C6-8AC0-48A3-A023-EDB3A7E6055D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D93AE1C6-8AC0-48A3-A023-EDB3A7E6055D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D93AE1C6-8AC0-48A3-A023-EDB3A7E6055D}.Release|Any CPU.Build.0 = Release|Any CPU
{C3CEAB63-E841-4585-BFF7-3A4BF9F78BE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C3CEAB63-E841-4585-BFF7-3A4BF9F78BE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C3CEAB63-E841-4585-BFF7-3A4BF9F78BE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C3CEAB63-E841-4585-BFF7-3A4BF9F78BE9}.Release|Any CPU.Build.0 = Release|Any CPU
{7671C02D-9D21-4124-97DE-80EB55879377}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7671C02D-9D21-4124-97DE-80EB55879377}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7671C02D-9D21-4124-97DE-80EB55879377}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7671C02D-9D21-4124-97DE-80EB55879377}.Release|Any CPU.Build.0 = Release|Any CPU
{F70CB8D4-71C1-466A-AEF9-91F4DD37988C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F70CB8D4-71C1-466A-AEF9-91F4DD37988C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F70CB8D4-71C1-466A-AEF9-91F4DD37988C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F70CB8D4-71C1-466A-AEF9-91F4DD37988C}.Release|Any CPU.Build.0 = Release|Any CPU
{CFD0ECE5-7675-45D6-AFEA-532983C6D1FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CFD0ECE5-7675-45D6-AFEA-532983C6D1FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CFD0ECE5-7675-45D6-AFEA-532983C6D1FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CFD0ECE5-7675-45D6-AFEA-532983C6D1FA}.Release|Any CPU.Build.0 = Release|Any CPU
{08EEA81C-62AF-464E-96A2-8F514B37CBE0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08EEA81C-62AF-464E-96A2-8F514B37CBE0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08EEA81C-62AF-464E-96A2-8F514B37CBE0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08EEA81C-62AF-464E-96A2-8F514B37CBE0}.Release|Any CPU.Build.0 = Release|Any CPU
{88CDA1EE-8CFF-4123-86F7-6FAE12CF01F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88CDA1EE-8CFF-4123-86F7-6FAE12CF01F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88CDA1EE-8CFF-4123-86F7-6FAE12CF01F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88CDA1EE-8CFF-4123-86F7-6FAE12CF01F9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
176 changes: 176 additions & 0 deletions examples/jetstream/interest-stream/dotnet2/Main.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
// Install NuGet packages `NATS.Net` and `Microsoft.Extensions.Logging.Console`.
using Microsoft.Extensions.Logging;
using NATS.Client.Core;
using NATS.Client.JetStream;
using NATS.Client.JetStream.Models;

using var loggerFactory = LoggerFactory.Create(builder => builder.AddConsole());
var logger = loggerFactory.CreateLogger("NATS-by-Example");

// `NATS_URL` environment variable can be used to pass the locations of the NATS servers.
var url = Environment.GetEnvironmentVariable("NATS_URL") ?? "127.0.0.1:4222";

// Connect to NATS server. Since connection is disposable at the end of our scope we should flush
// our buffers and close connection cleanly.
var opts = new NatsOpts
{
Url = url,
LoggerFactory = loggerFactory,
Name = "NATS-by-Example",
};
await using var nats = new NatsConnection(opts);

// Create `JetStream Context` which provides methods to create
// streams and consumers as well as convenience methods for publishing
// to streams and consuming messages from the streams.
var js = new NatsJSContext(nats);

// ### Creating the stream
// Define the stream configuration, specifying `InterestPolicy` for retention, and
// create the stream.
var config = new StreamConfig(name: "EVENTS", subjects: new[] { "events.>" })
{
Retention = StreamConfigRetention.Interest,
};

var stream = await js.CreateStreamAsync(config);

// To demonstrate the base case behavior of the stream without any consumers, we
// will publish a few messages to the stream.
await js.PublishAsync<object>(subject: "events.page_loaded", data: null);
await js.PublishAsync<object>(subject: "events.mouse_clicked", data: null);
var ack = await js.PublishAsync<object>(subject: "events.input_focused", data: null);
logger.LogInformation("Published 3 messages");

// We confirm that all three messages were published and the last message sequence
// is 3.
logger.LogInformation("Last message seq: {Seq}", ack.Seq);

// Checking out the stream info, notice how zero messages are present in
// the stream, but the `last_seq` is 3 which matches the last ACKed
// publish sequence above. Also notice that the `first_seq` is one greater
// which behaves as a sentinel value indicating the stream is empty. This
// sequence has not been assigned to a message yet, but can be interpreted
// as _no messages available_ in this context.
logger.LogInformation("# Stream info without any consumers");
await PrintStreamStateAsync(stream);

// ### Adding a consumer Now let's add a pull consumer and publish a few
// more messages. Also note that we are _only_ creating the consumer and
// have not yet started consuming the messages. This is only to point out
// that a it is not _required_ to be actively consuming messages to show
// _interest_, but it is the presence of a consumer which the stream cares
// about to determine retention of messages. [pull](/examples/jetstream/pull-consumer/dotnet2)
var consumer = await stream.CreateConsumerAsync(new ConsumerConfig("processor-1")
{
AckPolicy = ConsumerConfigAckPolicy.Explicit,
});

await js.PublishAsync<object>(subject: "events.page_loaded", data: null);
await js.PublishAsync<object>(subject: "events.mouse_clicked", data: null);

// If we inspect the stream info again, we will notice a few differences.
// It shows two messages (which we expect) and the first and last sequences
// corresponding to the two messages we just published. We also see that
// the `consumer_count` is now one.
logger.LogInformation("# Stream info with one consumer");
await PrintStreamStateAsync(stream);

await foreach (var msg in consumer.FetchAsync<string>(opts: new NatsJSFetchOpts { MaxMsgs = 2 }))
{
await msg.AckAsync(new AckOpts { DoubleAck = true });
}

// What do we expect in the stream? No messages and the `first_seq` has been set to
// the _next_ sequence number like in the base case.
// ☝️ As a quick aside on that second ack, We are using `AckSync` here for this
// example to ensure the stream state has been synced up for this subsequent
// retrieval.
logger.LogInformation("# Stream info with one consumer and acked messages");
await PrintStreamStateAsync(stream);

// ### Two or more consumers
// Since each consumer represents a separate _view_ over a stream, we would expect
// that if messages were processed by one consumer, but not the other, the messages
// would be retained. This is indeed the case.
var consumer2 = await stream.CreateConsumerAsync(new ConsumerConfig("processor-2")
{
AckPolicy = ConsumerConfigAckPolicy.Explicit,
});

await js.PublishAsync<object>(subject: "events.page_loaded", data: null);
await js.PublishAsync<object>(subject: "events.mouse_clicked", data: null);

// Here we fetch 2 messages for `processor-2`. There are two observations to
// make here. First the fetched messages are the latest two messages that
// were published just above and not any prior messages since these were
// already deleted from the stream. This should be apparent now, but this
// reinforces that a _late_ consumer cannot retroactively show interest. The
// second point is that the stream info shows that the latest two messages
// are still present in the stream. This is also expected since the first
// consumer had not yet processed them.
var msgMetas = new List<NatsJSMsgMetadata>();
await foreach (var msg in consumer2.FetchAsync<string>(opts: new NatsJSFetchOpts { MaxMsgs = 2 }))
{
await msg.AckAsync(new AckOpts { DoubleAck = true });
if (msg.Metadata is { } metadata)
{
msgMetas.Add(metadata);
}
}

logger.LogInformation("msg seqs {Seq1} and {Seq2}", msgMetas[0].Sequence.Stream, msgMetas[1].Sequence.Stream);

logger.LogInformation("# Stream info with two consumers, but only one set of acked messages");
await PrintStreamStateAsync(stream);

// Fetching and ack'ing from the first consumer subscription will result in the messages
// being deleted.
await foreach (var msg in consumer.FetchAsync<string>(opts: new NatsJSFetchOpts { MaxMsgs = 2 }))
{
await msg.AckAsync(new AckOpts { DoubleAck = true });
}

logger.LogInformation("# Stream info with two consumers having both acked");
await PrintStreamStateAsync(stream);

// A final callout is that _interest_ respects the `FilterSubject` on a consumer.
// For example, if a consumer defines a filter only for `events.mouse_clicked` events
// then it won't be considered _interested_ in events such as `events.input_focused`.
await stream.CreateConsumerAsync(new ConsumerConfig("processor-3")
{
AckPolicy = ConsumerConfigAckPolicy.Explicit,
FilterSubject = "events.mouse_clicked",
});

await js.PublishAsync<object>(subject: "events.input_focused", data: null);

// Fetch and `Terminate` (also works) and ack from the first consumers that _do_ have interest.
await foreach (var msg in consumer.FetchAsync<string>(opts: new NatsJSFetchOpts { MaxMsgs = 1 }))
{
await msg.AckTerminateAsync();
}

await foreach (var msg in consumer2.FetchAsync<string>(opts: new NatsJSFetchOpts { MaxMsgs = 1 }))
{
await msg.AckAsync(new AckOpts { DoubleAck = true });
}

logger.LogInformation("# Stream info with three consumers with interest from two");
await PrintStreamStateAsync(stream);

// That's it!
logger.LogInformation("Bye!");

async Task PrintStreamStateAsync(INatsJSStream jsStream)
{
await jsStream.RefreshAsync();
var state = jsStream.Info.State;
logger.LogInformation(
"Stream has messages:{Messages} first:{FirstSeq} last:{LastSeq} consumer_count:{ConsumerCount} num_subjects:{NumSubjects}",
state.Messages,
state.FirstSeq,
state.LastSeq,
state.ConsumerCount,
state.NumSubjects);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="NATS.Net" Version="2.0.0"/>
<PackageReference Include="NATS.Client.Serializers.Json" Version="2.0.0"/>
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
</ItemGroup>

</Project>
17 changes: 17 additions & 0 deletions examples/jetstream/interest-stream/dotnet2/output.cast
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{"version": 2, "width": 104, "height": 51, "timestamp": 1700974702, "env": {"SHELL": "/usr/bin/zsh", "TERM": "xterm-256color"}, "title": "NATS by Example: jetstream/interest-stream/dotnet2"}
[2.668687, "o", "info: NATS.Client.Core.NatsConnection[1001]\r\n Try to connect NATS nats://nats:4222\r\n"]
[2.705731, "o", "info: NATS.Client.Core.Internal.NatsReadProtocolProcessor[1005]\r\n Received server info: ServerInfo { Id = NDMT742URUINNER4MQPYJSWSTLJCQ2DYTPPGNBTX4JPLUM3K4D3XVTZL, Name = NDMT742URUINNER4MQPYJSWSTLJCQ2DYTPPGNBTX4JPLUM3K4D3XVTZL, Version = 2.10.4, ProtocolVersion = 1, GitCommit = abc47f7, GoVersion = go1.21.3, Host = 0.0.0.0, Port = 4222, HeadersSupported = True, AuthRequired = False, TlsRequired = False, TlsVerify = False, TlsAvailable = False, MaxPayload = 1048576, JetStreamAvailable = True, ClientId = 5, ClientIp = 192.168.144.3, Nonce = , Cluster = , ClusterDynamic = False, ClientConnectUrls = , WebSocketConnectUrls = , LameDuckMode = False }\r\n"]
[2.725147, "o", "info: NATS.Client.Core.NatsConnection[1001]\r\n Connect succeed NATS-by-Example, NATS nats://nats:4222\r\n"]
[2.81112, "o", "info: NATS-by-Example[0]\r\n Published 3 messages\r\ninfo: NATS-by-Example[0]\r\n Last message seq: 3\r\ninfo: NATS-by-Example[0]\r\n # Stream info without any consumers\r\n"]
[2.816307, "o", "info: NATS-by-Example[0]\r\n Stream has messages:0 first:4 last:3 consumer_count:0 num_subjects:0\r\n"]
[2.844571, "o", "info: NATS-by-Example[0]\r\n # Stream info with one consumer\r\n"]
[2.846404, "o", "info: NATS-by-Example[0]\r\n Stream has messages:2 first:4 last:5 consumer_count:1 num_subjects:2\r\n"]
[2.869248, "o", "info: NATS-by-Example[0]\r\n # Stream info with one consumer and acked messages\r\n"]
[2.869962, "o", "info: NATS-by-Example[0]\r\n Stream has messages:0 first:6 last:5 consumer_count:1 num_subjects:0\r\n"]
[2.876819, "o", "info: NATS-by-Example[0]\r\n msg seqs 6 and 7\r\ninfo: NATS-by-Example[0]\r\n # Stream info with two consumers, but only one set of acked messages\r\n"]
[2.87735, "o", "info: NATS-by-Example[0]\r\n Stream has messages:2 first:6 last:7 consumer_count:2 num_subjects:2\r\n"]
[2.878722, "o", "info: NATS-by-Example[0]\r\n # Stream info with two consumers having both acked\r\n"]
[2.879509, "o", "info: NATS-by-Example[0]\r\n Stream has messages:0 first:8 last:7 consumer_count:2 num_subjects:0\r\n"]
[2.88285, "o", "info: NATS-by-Example[0]\r\n # Stream info with three consumers with interest from two\r\n"]
[2.883439, "o", "info: NATS-by-Example[0]\r\n Stream has messages:0 first:9 last:8 consumer_count:3 num_subjects:0\r\ninfo: NATS-by-Example[0]\r\n Bye!\r\n"]
[2.884323, "o", "info: NATS.Client.Core.NatsConnection[1001]\r\n Disposing connection NATS-by-Example\r\n"]
Loading

1 comment on commit 748d38a

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deploy preview for nats-by-example ready!

✅ Preview
https://nats-by-example-go1vagq71-connecteverything.vercel.app

Built with commit 748d38a.
This pull request is being automatically deployed with vercel-action

Please sign in to comment.