Skip to content

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

@fabianmenges

Description

@fabianmenges

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)

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions