Skip to content

[BUG] fail-safe with a soft timeout : factory execution is stuck and not running to completion in .Net framework 4.7.2 and 4.8 #583

@JerinMathewJose01

Description

@JerinMathewJose01

Describe the bug

Factory is not executing in the background for .Net Framework 4.7.2 and Framework 4.8 .

To Reproduce

Here's a MRE (Minimal Reproducible Example) of the issue:

 /// </summary>
/// <param name="id"></param>
/// <returns></returns>
[Route("FusionTest/{id:int}")]
[HttpGet]
public async Task <IHttpActionResult> FusionTest(int id) {
  //This is a demo method
  string key = "Data" + id;
  string traceId = Guid.NewGuid().ToString().Substring(0, 4);
  var data = await CacheConfig.Instance.GetOrSetAsync <string> (
    key,
    async (ctx, ct) => {
        Log.Information("[{TraceId}] FACTORY STARTING on Thread {Tid} - {key}", traceId, Environment.CurrentManagedThreadId, key);
        try {
          var result = await FetchDataFromDb(id);
          Log.Information("[{TraceId}] FACTORY SUCCESS on Thread {Tid} - {key}", traceId, Environment.CurrentManagedThreadId, key);
          return result;
        } catch (Exception ex) {
          Log.Error(ex, "[{TraceId}] FACTORY FAILED!", traceId);
          throw;
        }
      }, "default value",
      options => options
        .SetDuration(TimeSpan.FromSeconds(5))
        .SetFailSafe(true, TimeSpan.FromHours(1), TimeSpan.FromSeconds(5))
        .SetFactoryTimeouts(TimeSpan.FromSeconds(1), null, true)
        .AllowTimedOutFactoryBackgroundCompletion = true
  );
  return Ok(data);
}
private async Task <string> FetchDataFromDb(int id) {
  await Task.Delay(5000);
  return $ "Value for {id}";
}

public static class CacheConfig {
  private static readonly Lazy <IFusionCache> _cache = new Lazy <IFusionCache> (() => {
    // 1. Configure Serilog (if not already done in Global.asax)
    Log.Logger = new LoggerConfiguration()
      .MinimumLevel.Information()
      .MinimumLevel.Override("ZiggyCreatures.Caching.Fusion", LogEventLevel.Warning)
      .WriteTo.File(
        path: @ "C:\Logs\API.FusionCacheLog48Test.txt",
        rollingInterval: RollingInterval.Day,
        retainedFileCountLimit: 7,
        shared: true
      )
      .CreateLogger();
    // 2. Create the Bridge between Serilog and FusionCache
    var loggerFactory = new LoggerFactory();
    var fusionLogger = loggerFactory.CreateLogger <FusionCache> ();
    // 3. Setup FusionCache Options
    var options = new FusionCacheOptions {
      DefaultEntryOptions = new FusionCacheEntryOptions().SetDuration(TimeSpan.FromMinutes(10)),
    };
    // 4. Initialize the Cache
    var cache = new FusionCache(options, logger: fusionLogger);
    return cache;
  });
  /// <summary>
  ///
  /// </summary>
  public static IFusionCache Instance => _cache.Value;
}

Expected behavior

  • If the cache is empty - Wait for the factory to complete and get the result (Since no FactoryHardTimeout specified)- Working as expected
  • If a soft FactorySoftTimeout occurs trigger failsafe and return the cached value - Working as expected
  • Complete the execution in background and made available in the cache for subsequent request - Not working

Versions

I've encountered this issue on:

  • FusionCache version 2.5.0
  • .NET version 4.7.2 & 4.8
  • OS version Windows Server 2022 Data Center
  • others - Memory . This has not deployed yet .Using Visual Studio Professional 2022 . The above scenario is working fine in .NET 8 but not in legacy .Net Framework 4.7.2 or 4.8

Screenshots

If applicable, add screenshots to help explain your problem.

Additional context

The above scenario is working fine in .NET 8 but not in legacy .Net Framework 4.7.2 or 4.8

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions