feat: complete final jetstream parity transport and runtime baselines

This commit is contained in:
Joseph Doherty
2026-02-23 11:04:43 -05:00
parent 53585012f3
commit 8bce096f55
61 changed files with 2655 additions and 129 deletions

View File

@@ -41,6 +41,20 @@ internal sealed class JetStreamApiFixture : IAsyncDisposable
return fixture;
}
public static Task<JetStreamApiFixture> StartWithStreamConfigAsync(StreamConfig config)
{
var fixture = new JetStreamApiFixture();
_ = fixture._streamManager.CreateOrUpdate(config);
return Task.FromResult(fixture);
}
public static async Task<JetStreamApiFixture> StartWithStreamJsonAsync(string json)
{
var fixture = new JetStreamApiFixture();
_ = await fixture.RequestLocalAsync("$JS.API.STREAM.CREATE.S", json);
return fixture;
}
public static async Task<JetStreamApiFixture> StartWithPullConsumerAsync()
{
var fixture = await StartWithStreamAsync("ORDERS", "orders.*");
@@ -82,6 +96,47 @@ internal sealed class JetStreamApiFixture : IAsyncDisposable
return fixture;
}
public static async Task<JetStreamApiFixture> StartWithMultiFilterConsumerAsync()
{
var fixture = await StartWithStreamAsync("ORDERS", ">");
_ = await fixture.CreateConsumerAsync("ORDERS", "CF", null, filterSubjects: ["orders.*"]);
return fixture;
}
public static async Task<JetStreamApiFixture> StartWithReplayOriginalConsumerAsync()
{
var fixture = await StartWithStreamAsync("ORDERS", "orders.*");
_ = await fixture.PublishAndGetAckAsync("orders.created", "1");
_ = await fixture.CreateConsumerAsync("ORDERS", "RO", "orders.*", replayPolicy: ReplayPolicy.Original, ackPolicy: AckPolicy.Explicit);
return fixture;
}
public static Task<JetStreamApiFixture> StartWithMultipleSourcesAsync()
{
var fixture = new JetStreamApiFixture();
_ = fixture._streamManager.CreateOrUpdate(new StreamConfig
{
Name = "SRC1",
Subjects = ["a.>"],
});
_ = fixture._streamManager.CreateOrUpdate(new StreamConfig
{
Name = "SRC2",
Subjects = ["b.>"],
});
_ = fixture._streamManager.CreateOrUpdate(new StreamConfig
{
Name = "AGG",
Subjects = ["agg.>"],
Sources =
[
new StreamSourceConfig { Name = "SRC1" },
new StreamSourceConfig { Name = "SRC2" },
],
});
return Task.FromResult(fixture);
}
public static Task<JetStreamApiFixture> StartJwtLimitedAccountAsync(int maxStreams)
{
var account = new Account("JWT-LIMITED")
@@ -148,9 +203,45 @@ internal sealed class JetStreamApiFixture : IAsyncDisposable
return _streamManager.GetStateAsync(streamName, default).AsTask();
}
public Task<JetStreamApiResponse> CreateConsumerAsync(string stream, string durableName, string filterSubject, bool push = false, int heartbeatMs = 0, AckPolicy ackPolicy = AckPolicy.None, int ackWaitMs = 30_000)
public Task<string> GetStreamBackendTypeAsync(string streamName)
{
var payload = $@"{{""durable_name"":""{durableName}"",""filter_subject"":""{filterSubject}"",""push"":{push.ToString().ToLowerInvariant()},""heartbeat_ms"":{heartbeatMs},""ack_policy"":""{ackPolicy.ToString().ToLowerInvariant()}"",""ack_wait_ms"":{ackWaitMs}}}";
return Task.FromResult(_streamManager.GetStoreBackendType(streamName));
}
public Task<JetStreamApiResponse> CreateConsumerAsync(
string stream,
string durableName,
string? filterSubject,
bool push = false,
int heartbeatMs = 0,
AckPolicy ackPolicy = AckPolicy.None,
int ackWaitMs = 30_000,
int maxAckPending = 0,
IReadOnlyList<string>? filterSubjects = null,
ReplayPolicy replayPolicy = ReplayPolicy.Instant,
DeliverPolicy deliverPolicy = DeliverPolicy.All,
bool ephemeral = false)
{
var payloadObj = new
{
durable_name = durableName,
filter_subject = filterSubject,
filter_subjects = filterSubjects,
push,
heartbeat_ms = heartbeatMs,
ack_policy = ackPolicy.ToString().ToLowerInvariant(),
ack_wait_ms = ackWaitMs,
max_ack_pending = maxAckPending,
replay_policy = replayPolicy == ReplayPolicy.Original ? "original" : "instant",
deliver_policy = deliverPolicy switch
{
DeliverPolicy.Last => "last",
DeliverPolicy.New => "new",
_ => "all",
},
ephemeral,
};
var payload = JsonSerializer.Serialize(payloadObj);
return RequestLocalAsync($"$JS.API.CONSUMER.CREATE.{stream}.{durableName}", payload);
}
@@ -206,6 +297,12 @@ internal sealed class JetStreamApiFixture : IAsyncDisposable
_ = await PublishAndGetAckAsync(subject, payload);
}
public Task PublishToSourceAsync(string sourceStream, string subject, string payload)
{
_ = sourceStream;
return PublishAndGetAckAsync(subject, payload);
}
public Task AckAllAsync(string stream, string durableName, ulong sequence)
{
_consumerManager.AckAll(stream, durableName, sequence);