Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent KeyValueStore error when MaxAge is set below the default DuplicateWindow value #362

Merged
merged 1 commit into from
Mar 11, 2024

Conversation

rickdotnet
Copy link
Collaborator

When setting a MaxAge less than the default DuplicateWindow value, you receive the following error. This PR fixes this.

NATS.Client.JetStream.NatsJSApiException: duplicates window can not be larger then max age
   at NATS.Client.JetStream.Internal.NatsJSResponse`1.EnsureSuccess() in C:\SourceControl\Random\nats.net.v2\src\NATS.Client.JetStream\Internal\NatsJSResponse.cs:line 27
   at NATS.Client.JetStream.NatsJSContext.JSRequestResponseAsync[TRequest,TResponse](String subject, TRequest request, CancellationToken cancellationToken) in C:\SourceControl\Random\nats.net.v2\src\NATS.Client.JetStream\NatsJSContext.cs:line 185
   at NATS.Client.JetStream.NatsJSContext.CreateStreamAsync(StreamConfig config, CancellationToken cancellationToken) in C:\SourceControl\Random\nats.net.v2\src\NATS.Client.JetStream\NatsJSContext.Streams.cs:line 21
   at NATS.Client.KeyValueStore.NatsKVContext.CreateStoreAsync(NatsKVConfig config, CancellationToken cancellationToken) in C:\SourceControl\Random\nats.net.v2\src\NATS.Client.KeyValueStore\NatsKVContext.cs:line 115
   at Program.<Main>$(String[] args) in C:\SourceControl\Random\nats.net.v2\sandbox\Example.KeyValueStore.Watcher\Program.cs:line 18
   at Program.<Main>(String[] args)

Modified Example.KeyValueStore.Watcher code to reproduce:

var nats = new NatsConnection();

var js = new NatsJSContext(nats);
var kv = new NatsKVContext(js);

var config = new NatsKVConfig("e1")
{
    MaxAge = TimeSpan.FromSeconds(30),
};

var store = await kv.CreateStoreAsync(config);

await foreach (var entry in store.WatchAsync<int>())
{
    Console.WriteLine($"[RCV] {entry}");
}

@mtmk
Copy link
Collaborator

mtmk commented Jan 28, 2024

Our general policy is not to fix validation issues but throw validation exception.

@rickdotnet
Copy link
Collaborator Author

rickdotnet commented Jan 28, 2024

Interesting. I wouldn't expect JS exceptions when operating with the K/V store. But, can fix on my end. No problem.

This would effectively limit MaxAge to >2min. Anything less than this would result in an error.

@rickdotnet rickdotnet closed this Jan 28, 2024
@mtmk
Copy link
Collaborator

mtmk commented Jan 28, 2024

I didn't mean to close the PR. it's a good use case. I think we should validate the config in kv.CreateStoreAsync(config) before sending it to the server. I personally like your approach but throwing an exception is our validation approach in NATS clients in general.

Edit: Apologies, you're right! 👇

@mtmk mtmk reopened this Jan 28, 2024
@mtmk
Copy link
Collaborator

mtmk commented Jan 28, 2024

Actually what you've done seems to be the correct thing:

https://github.com/nats-io/nats.go/blob/98430acd80423b776149f29d625d158f490ac3c5/jetstream/kv.go#L334-L342

I didn't realised duplicate window wasn't actually part of KV config.

@mtmk mtmk mentioned this pull request Feb 18, 2024
Copy link
Collaborator

@mtmk mtmk left a comment

Choose a reason for hiding this comment

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

LGTM thanks @rickdotnet 💯

@mtmk mtmk removed the in-progress label Mar 3, 2024
@mtmk mtmk added this to the 2.1.3 milestone Mar 3, 2024
@mtmk mtmk merged commit 5cbe4e2 into nats-io:main Mar 11, 2024
10 checks passed
mtmk added a commit that referenced this pull request Mar 11, 2024
@mtmk mtmk mentioned this pull request Mar 11, 2024
mtmk added a commit that referenced this pull request Mar 12, 2024
@@ -108,9 +108,13 @@ public async ValueTask<INatsKVStore> CreateStoreAsync(NatsKVConfig config, Cance
// MirrorDirect =
// Mirror =
Retention = StreamConfigRetention.Limits, // from ADR-8
DuplicateWindow = TimeSpan.FromMinutes(2), // 120_000_000_000ns, from ADR-8
DuplicateWindow = config.MaxAge != default ? config.MaxAge : TimeSpan.FromMinutes(2), // 120_000_000_000ns, from ADR-8
Copy link
Collaborator

Choose a reason for hiding this comment

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

my fault didn't check setting duplicate-window to max-age here should've been removed

- DuplicateWindow = config.MaxAge != default ? config.MaxAge : TimeSpan.FromMinutes(2), // 120_000_000_000ns, from ADR-8
+ DuplicateWindow = TimeSpan.FromMinutes(2), // 120_000_000_000ns, from ADR-8

cc @scottf

Background: When setting max age default window is always set equals to max age. e.g. if we set max-age=30 minute default windows should still stay at 2 minutes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants