Skip to content

Commit 0098978

Browse files
authoredApr 4, 2025··
Add support for pedantic mode in consumer creation (#264)
Introduced a `pedantic` option in `ConsumerApiOptions` to ensure stricter validation of consumer configuration during creation. Updated the `add` method in `jsmconsumer_api.ts` to handle this option, and added a test case to validate pedantic behavior. This enhances flexibility while enforcing stricter checks when needed. Note the original API allowed for an optional action (a string), now it also allows a ConsumerApiOptions object that allows setting the action and whether it should be pedantic. Signed-off-by: Alberto Ricart <alberto@synadia.com>
1 parent ba6a8cc commit 0098978

File tree

4 files changed

+57
-3
lines changed

4 files changed

+57
-3
lines changed
 

‎jetstream/src/jsapi_types.ts

+9
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,14 @@ export type PurgeResponse = Success & {
718718
purged: number;
719719
};
720720

721+
/**
722+
* Additional options that express the intention of the API
723+
*/
724+
export type ConsumerApiOptions = ConsumerApiAction | {
725+
action?: ConsumerApiAction;
726+
pedantic?: boolean;
727+
};
728+
721729
export const ConsumerApiAction = {
722730
CreateOrUpdate: "",
723731
Update: "update",
@@ -730,6 +738,7 @@ export type CreateConsumerRequest = {
730738
"stream_name": string;
731739
config: Partial<ConsumerConfig>;
732740
action?: ConsumerApiAction;
741+
pedantic?: boolean;
733742
};
734743

735744
export type StreamMsgResponse = ApiResponse & {

‎jetstream/src/jsmconsumer_api.ts

+8-2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import {
3030
InvalidArgumentError,
3131
} from "@nats-io/nats-core/internal";
3232
import type {
33+
ConsumerApiOptions,
3334
ConsumerConfig,
3435
ConsumerInfo,
3536
ConsumerListResponse,
@@ -55,10 +56,14 @@ export class ConsumerAPIImpl extends BaseApiClientImpl implements ConsumerAPI {
5556
async add(
5657
stream: string,
5758
cfg: ConsumerConfig,
58-
action: ConsumerApiAction = ConsumerApiAction.Create,
59+
opts: ConsumerApiOptions = ConsumerApiAction.Create,
5960
): Promise<ConsumerInfo> {
6061
validateStreamName(stream);
6162

63+
if (typeof opts === "string") {
64+
opts = { action: opts as ConsumerApiAction };
65+
}
66+
6267
if (cfg.deliver_group && cfg.flow_control) {
6368
throw InvalidArgumentError.format(
6469
["flow_control", "deliver_group"],
@@ -89,7 +94,8 @@ export class ConsumerAPIImpl extends BaseApiClientImpl implements ConsumerAPI {
8994
const cr = {} as CreateConsumerRequest;
9095
cr.config = cfg;
9196
cr.stream_name = stream;
92-
cr.action = action;
97+
cr.action = opts.action;
98+
cr.pedantic = opts.pedantic;
9399

94100
if (cr.config.durable_name) {
95101
validateDurableName(cr.config.durable_name);

‎jetstream/src/types.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import type {
2323
} from "@nats-io/nats-core/internal";
2424

2525
import type {
26+
ConsumerApiOptions,
2627
DeliverPolicy,
2728
DirectLastFor,
2829
PullOptions,
@@ -271,7 +272,11 @@ export type ConsumerAPI = {
271272
* @param stream
272273
* @param cfg
273274
*/
274-
add(stream: string, cfg: Partial<ConsumerConfig>): Promise<ConsumerInfo>;
275+
add(
276+
stream: string,
277+
cfg: Partial<ConsumerConfig>,
278+
opts?: ConsumerApiOptions,
279+
): Promise<ConsumerInfo>;
275280

276281
/**
277282
* Updates the consumer configuration for the specified consumer on the specified

‎jetstream/tests/jsm_test.ts

+34
Original file line numberDiff line numberDiff line change
@@ -2599,6 +2599,40 @@ Deno.test("jsm - pause/unpause", async () => {
25992599
await cleanup(ns, nc);
26002600
});
26012601

2602+
Deno.test("jsm - consumer pedantic", async () => {
2603+
const { ns, nc } = await setup(jetstreamServerConf());
2604+
const jsm = await jetstreamManager(nc);
2605+
await jsm.streams.add({
2606+
name: "A",
2607+
subjects: ["a"],
2608+
storage: StorageType.Memory,
2609+
consumer_limits: {
2610+
max_ack_pending: 10,
2611+
},
2612+
});
2613+
2614+
// this should work
2615+
await jsm.consumers.add("A", {
2616+
name: "a",
2617+
ack_policy: AckPolicy.Explicit,
2618+
});
2619+
2620+
// but this should reject
2621+
await assertRejects(
2622+
() => {
2623+
return jsm.consumers.add("A", {
2624+
name: "b",
2625+
ack_policy: AckPolicy.Explicit,
2626+
max_ack_pending: 0,
2627+
}, { pedantic: true });
2628+
},
2629+
Error,
2630+
"pedantic mode: max_ack_pending must be set if it's configured in stream limits",
2631+
);
2632+
2633+
await cleanup(ns, nc);
2634+
});
2635+
26022636
Deno.test("jsm - storage", async () => {
26032637
const { ns, nc } = await setup(jetstreamServerConf());
26042638

0 commit comments

Comments
 (0)
Please sign in to comment.