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

[BUG] Combining Jitter and FailSafeThrottleDuration leads to wrong or at least unexpected behavior #374

Open
fabianmenges opened this issue Jan 31, 2025 · 1 comment

Comments

@fabianmenges
Copy link

fabianmenges commented Jan 31, 2025

Describe the bug

I'm using a 2 level cache, MemoryCache + Redis with the FailSafe option enabled.

  • I don't want my DefaultFailSafe value to be cached at all - which means i need to set the FailSafeThrottleDuration to TimeSpan.Zero.
  • I still want to add jitter for the caching duration of non-default values.
    It seems like jitter is also applied to to the FailSafeThrottleDuration - which is unexpected and in my case undesired behavior.

To Reproduce

In my opinion this should not throw an exception (but it does):

    public async ValueTask Test() {
        var expectedNegOne = await _cache.GetOrSetAsync<int>("111derp",
            (ctx, ct) => Task.FromResult(ctx.Fail("test")),
            failSafeDefaultValue: -1,
            options => options
                .SetDuration(TimeSpan.FromMinutes(value: 180))
                .SetJittering(TimeSpan.FromMinutes(value: 30))
                .SetFailSafe(isEnabled: true, throttleDuration: TimeSpan.Zero)
        );
        await Task.Delay(TimeSpan.FromSeconds(value: 5));
        var expectedOne = await _cache.GetOrSetAsync<int>("111derp",
            (ctx, ct) => Task.FromResult(ctx.Modified(value: 1)),
            failSafeDefaultValue: -1,
            options => options
                .SetDuration(TimeSpan.FromMinutes(value: 180))
                .SetJittering(TimeSpan.FromMinutes(value: 30))
                .SetFailSafe(isEnabled: true, throttleDuration: TimeSpan.Zero)
        );

        if (expectedNegOne != -1) {
            throw new Exception("Expected -1");
        }
        if (expectedOne != 1) {
            throw new Exception("Expected 1");
        }
    }

Expected behavior

I would have expected the code above to perform identically to this code:

    public async ValueTask Test() {
        var expectedNegOne = await _cache.GetOrSetAsync<int>("111derp",
            (ctx, ct) => Task.FromResult(ctx.Fail("test")),
            failSafeDefaultValue: -1,
            options => options
                .SetDuration(TimeSpan.FromMinutes(value: 180))
                .SetFailSafe(isEnabled: true, throttleDuration: TimeSpan.Zero)
        );
        await Task.Delay(TimeSpan.FromSeconds(value: 5));
        var expectedOne = await _cache.GetOrSetAsync<int>("111derp",
            (ctx, ct) => Task.FromResult(ctx.Modified(value: 1)),
            failSafeDefaultValue: -1,
            options => options
                .SetDuration(TimeSpan.FromMinutes(value: 180))
                .SetFailSafe(isEnabled: true, throttleDuration: TimeSpan.Zero)
        );

        if (expectedNegOne != -1) {
            throw new Exception("Expected -1");
        }
        if (expectedOne != 1) {
            throw new Exception("Expected 1");
        }
    }

Versions

I've encountered this issue on:

  • FusionCache version 1.4.1
  • .NET version net8.0
  • OS version Ubuntu 24.04.1 LTS (Noble Numbat)
  • Using Redis (should not play a role - I have not tested it without redis)
@jodydonetti
Copy link
Collaborator

jodydonetti commented Feb 5, 2025

Hi @fabianmenges , I think you're right: jittering should not be considered when doing fail-safe throttling.

I'll think about it a bit more and, if nothing comes up, I'll do the change.

Will update you, meanwhile thanks for bringing this up!

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