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

Removing DuplicateWindow rules in NatsKVContext.CreateStoreAsync makes recreation of bucket fail #736

Open
MiloszKrajewski opened this issue Feb 4, 2025 · 2 comments

Comments

@MiloszKrajewski
Copy link

MiloszKrajewski commented Feb 4, 2025

Observed behavior

NOTE: I did the investigation, so reasons are all known, the question is really about how to address it properly.

After upgrading to newer version NatsKVContext.CreateStoreAsync started to throw an "stream already exists with different configuration" error when trying to recreate bucket even though we did not change any bucket configuration.

Expected behavior

As we did not change configuration, therefore we would expect it to work as it worked before.

Server and client version

nats-server: 2.10.14
nats.net: 2.5.5 (but also later)

Host environment

docker image / docker desktop / windows 11

Steps to reproduce

Commit which broke it: 4832d15

Create bucket with MaxAge set to 1h with version before mentioned commit, then upgrade to 2.5.5 and recreate bucket. It will fail.

Before this commit, DuplicateWindows was set to:

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

which was removed, and now it is default value (which is 2 min, I think).

This causes exception "stream already exists with different configuration" when using CreateStoreAsync even though we did not change any configuration of our store.

I understand that new code is probably better (2 min for deduplication makes sense), however I would like to address it somehow without dropping my old stream.

For now I ended up with something like this, just ignoring potential error.

private static async Task<INatsKVStore> GetOrCreateStore(INatsKVContext context, NatsKVConfig config)
{
    try
    {
        return await context.CreateStoreAsync(config);
    }
    catch (NatsJSApiException e) when (e.Error.ErrCode == 10058)
    {
        // stream already exists with different configuration
        // let's say we are ok with it for now
        return await context.GetStoreAsync(config.Bucket);
    }
}

but what are my options? What would be recommended way to do it? How to recreate bucket without loosing data?

@MiloszKrajewski MiloszKrajewski changed the title Removing DuplicateWindow from KV Store forces recreation of old streams Removing DuplicateWindow rules in NatsKVContext.CreateStoreAsync makes recreation of bucket fail Feb 4, 2025
@mtmk
Copy link
Collaborator

mtmk commented Feb 5, 2025

Thanks for the report, @MiloszKrajewski. It's a subtle but nasty breaking change that I didn't realize at the time. Apologies for that. I have a couple of suggestions:

Option 1: The easiest solution I can think of is to perform a one-off update to set your backing stream's duplicate window to 2 minutes instead.

Option 2: If you have a mixture of client versions, you can also implement a check before or after (depending on the version in use) until all your applications are upgraded. For example:

var kvBackingStream = await js.GetStreamAsync($"KV_{bucket}");
if (kvBackingStream.Info.Config.DuplicateWindow != TimeSpan.FromMinutes(2))
{
    kvBackingStream.Info.Config.DuplicateWindow = TimeSpan.FromMinutes(2);
    await kvBackingStream.UpdateAsync(kvBackingStream.Info.Config);
}

WDYT? Would that work for you?

@mtmk
Copy link
Collaborator

mtmk commented Feb 5, 2025

⚠ btw you should move away from 2.5.5 (deprecated on NuGet as well) there is a bug in that version intermittently messes up JetStream API serialization. see 2.5.6 release notes https://github.com/nats-io/nats.net/releases/tag/v2.5.6

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

No branches or pull requests

2 participants