private IFusionCacheEntry?GetOrSetEntryInternal <TValue>(string operationId, string key, Func <CancellationToken, TValue>?factory, FusionCacheEntryOptions?options, CancellationToken token)
        {
            if (options is null)
            {
                options = _options.DefaultEntryOptions;
            }

            token.ThrowIfCancellationRequested();

            FusionCacheMemoryEntry?_memoryEntry;
            bool _memoryEntryIsValid;

            // DIRECTLY CHECK MEMORY CACHE (TO AVOID LOCKING)
            (_memoryEntry, _memoryEntryIsValid) = _mca.TryGetEntry <TValue>(operationId, key);
            if (_memoryEntryIsValid)
            {
                if (_logger?.IsEnabled(LogLevel.Trace) ?? false)
                {
                    _logger.LogTrace("FUSION (K={CacheKey} OP={CacheOperationId}): using memory entry", key, operationId);
                }
                return(_memoryEntry);
            }

            var dca = GetCurrentDistributedAccessor();

            // SHORT-CIRCUIT: NO FACTORY AND NO USABLE DISTRIBUTED CACHE
            if (factory is null && (dca?.IsCurrentlyUsable() ?? false) == false)
            {
                if (options.IsFailSafeEnabled && _memoryEntry is object)
                {
                    if (_logger?.IsEnabled(LogLevel.Trace) ?? false)
                    {
                        _logger.LogTrace("FUSION (K={CacheKey} OP={CacheOperationId}): using memory entry (expired)", key, operationId);
                    }
                    return(_memoryEntry);
                }

                return(null);
            }

            IFusionCacheEntry?_entry;

            // LOCK
            var lockObj = _reactor.AcquireLock(key, operationId, options.LockTimeout, _logger);

            try
            {
                // TRY AGAIN WITH MEMORY CACHE (AFTER THE LOCK HAS BEEN ACQUIRED, MAYBE SOMETHING CHANGED)
                (_memoryEntry, _memoryEntryIsValid) = _mca.TryGetEntry <TValue>(operationId, key);
                if (_memoryEntryIsValid)
                {
                    if (_logger?.IsEnabled(LogLevel.Trace) ?? false)
                    {
                        _logger.LogTrace("FUSION (K={CacheKey} OP={CacheOperationId}): using memory entry", key, operationId);
                    }
                    return(_memoryEntry);
                }

                // TRY WITH DISTRIBUTED CACHE (IF ANY)
                FusionCacheDistributedEntry <TValue>?distributedEntry = null;
                bool distributedEntryIsValid = false;

                if (dca?.IsCurrentlyUsable() ?? false)
                {
                    (distributedEntry, distributedEntryIsValid) = dca.TryGetEntry <TValue>(operationId, key, options, _memoryEntry is object, token);
                }

                if (distributedEntryIsValid)
                {
                    _entry = FusionCacheMemoryEntry.CreateFromOptions(distributedEntry !.Value, options, false);
                }
                else
                {
                    TValue value;
                    bool   failSafeActivated = false;

                    if (factory is null)
                    {
                        // NO FACTORY

                        var fallbackEntry = MaybeGetFallbackEntry(operationId, key, distributedEntry, _memoryEntry, options, out failSafeActivated);
                        if (fallbackEntry is object)
                        {
                            value = fallbackEntry.GetValue <TValue>();
                        }
                        else
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        // FACTORY

                        Task <TValue>?factoryTask = null;

                        try
                        {
                            var timeout = options.GetAppropriateFactoryTimeout(_memoryEntry is object || distributedEntry is object);

                            if (_logger?.IsEnabled(LogLevel.Debug) ?? false)
                            {
                                _logger.LogDebug("FUSION (K={CacheKey} OP={CacheOperationId}): calling the factory (timeout={Timeout})", key, operationId, timeout.ToLogString_Timeout());
                            }

                            value = FusionCacheExecutionUtils.RunSyncFuncWithTimeout(ct => factory(ct), timeout, options.AllowTimedOutFactoryBackgroundCompletion == false, x => factoryTask = x, token);
                        }
                        catch (OperationCanceledException)
                        {
                            throw;
                        }
                        catch (Exception exc)
                        {
                            ProcessFactoryError(operationId, key, exc);

                            MaybeBackgroundCompleteTimedOutFactory <TValue>(operationId, key, factoryTask, options, dca, token);

                            var fallbackEntry = MaybeGetFallbackEntry(operationId, key, distributedEntry, _memoryEntry, options, out failSafeActivated);
                            if (fallbackEntry is object)
                            {
                                value = fallbackEntry.GetValue <TValue>();
                            }
                            else
                            {
                                throw;
                            }
                        }
                    }

                    _entry = FusionCacheMemoryEntry.CreateFromOptions(value, options, failSafeActivated);

                    if ((dca?.IsCurrentlyUsable() ?? false) && failSafeActivated == false)
                    {
                        // SAVE IN THE DISTRIBUTED CACHE (BUT ONLY IF NO FAIL-SAFE HAS BEEN EXECUTED)
                        dca.SetEntry <TValue>(operationId, key, _entry, options);
                    }
                }

                // SAVING THE DATA IN THE MEMORY CACHE (EVEN IF IT IS FROM FAIL-SAFE)
                if (_entry is object)
                {
                    _mca.SetEntry <TValue>(operationId, key, _entry.AsMemoryEntry(), options);
                }
            }
            finally
            {
                ReleaseLock(operationId, key, lockObj);
            }

            return(_entry);
        }
        private IFusionCacheEntry?MaybeGetFallbackEntry <TValue>(string operationId, string key, FusionCacheDistributedEntry <TValue>?distributedEntry, FusionCacheMemoryEntry?memoryEntry, FusionCacheEntryOptions options, out bool failSafeActivated)
        {
            failSafeActivated = false;

            if (options.IsFailSafeEnabled)
            {
                if (_logger?.IsEnabled(LogLevel.Trace) ?? false)
                {
                    _logger.LogTrace("FUSION (K={CacheKey} OP={CacheOperationId}): trying to activate FAIL-SAFE", key, operationId);
                }
                if (distributedEntry is object)
                {
                    // FAIL SAFE (FROM DISTRIBUTED)
                    if (_logger?.IsEnabled(_options.FailSafeActivationLogLevel) ?? false)
                    {
                        _logger.Log(_options.FailSafeActivationLogLevel, "FUSION (K={CacheKey} OP={CacheOperationId}): FAIL-SAFE activated (from distributed)", key, operationId);
                    }
                    failSafeActivated = true;
                    return(distributedEntry);
                }
                else if (memoryEntry is object)
                {
                    // FAIL SAFE (FROM MEMORY)
                    if (_logger?.IsEnabled(_options.FailSafeActivationLogLevel) ?? false)
                    {
                        _logger.Log(_options.FailSafeActivationLogLevel, "FUSION (K={CacheKey} OP={CacheOperationId}): FAIL-SAFE activated (from memory)", key, operationId);
                    }
                    failSafeActivated = true;
                    return(memoryEntry);
                }
                else
                {
                    if (_logger?.IsEnabled(_options.FailSafeActivationLogLevel) ?? false)
                    {
                        _logger.Log(_options.FailSafeActivationLogLevel, "FUSION (K={CacheKey} OP={CacheOperationId}): unable to activate FAIL-SAFE (no entries in memory or distributed)", key, operationId);
                    }
                    return(null);
                }
            }
            else
            {
                if (_logger?.IsEnabled(LogLevel.Trace) ?? false)
                {
                    _logger.LogTrace("FUSION (K={CacheKey} OP={CacheOperationId}): FAIL-SAFE not enabled", key, operationId);
                }
                return(null);
            }
        }