private async Task <TResult> ExecuteAsync <TResult>(
            OperationContext context,
            ContentMetadataStoreModeFlags modeMask,
            Func <IContentMetadataStore, Task <TResult> > executeAsync,
            string caller)
            where TResult : ResultBase
        {
            var flags     = _configuration.ContentMetadataStoreModeFlags & modeMask;
            var redisTask = MeasuredExecuteAsync(_redisStore, flags & ContentMetadataStoreModeFlags.Redis, executeAsync);

            string extraEndMessage    = null;
            var    combinedResultTask = context.PerformOperationAsync(
                Tracer,
                async() =>
            {
                var distributedTask = MeasuredExecuteAsync(_distributedStore, flags & ContentMetadataStoreModeFlags.Distributed, executeAsync);
                var(redisResult, distributedResult) = await WhenBothAsync(redisTask, distributedTask);
                var result      = _preferDistributed ? distributedResult : redisResult;
                extraEndMessage = $"Redis={redisResult.message}, Distrib={distributedResult.message}";
                return(result.result);
            },
                caller: caller,
                extraEndMessage: r => extraEndMessage);

            if ((flags & ContentMetadataStoreModeFlags.PreferRedis) != 0)
            {
                // If preferring redis, return the redis result without waiting for combined result
                return((await redisTask).result);
            }
            else
            {
                return(await combinedResultTask);
            }
        }
        public TransitioningGlobalCacheStore(RedisContentLocationStoreConfiguration configuration, IGlobalCacheStore redisStore, IGlobalCacheStore distributedStore)
        {
            Contract.Requires(configuration.AllContentMetadataStoreModeFlags.HasAnyFlag(ContentMetadataStoreModeFlags.Redis) &&
                              configuration.AllContentMetadataStoreModeFlags.HasAnyFlag(ContentMetadataStoreModeFlags.Distributed),
                              "Transitioning store should not used for cases where one store or the other is used exclusively");

            _configuration    = configuration;
            _redisStore       = redisStore;
            _distributedStore = distributedStore;

            if (BlobMode.HasAllFlags(ContentMetadataStoreModeFlags.PreferRedis) || BlobMode.MaskFlags(ContentMetadataStoreModeFlags.Distributed) == 0)
            {
                AreBlobsSupported = _redisStore.AreBlobsSupported;
            }
            else if (BlobMode.HasAllFlags(ContentMetadataStoreModeFlags.PreferDistributed) || BlobMode.MaskFlags(ContentMetadataStoreModeFlags.Redis) == 0)
            {
                AreBlobsSupported = _distributedStore.AreBlobsSupported;
            }
            else
            {
                AreBlobsSupported = _redisStore.AreBlobsSupported || _distributedStore.AreBlobsSupported;
            }

            // Mask used to only include valid flags for BlobMode based on blob support in the respective stores
            _blobSupportedMask = ContentMetadataStoreModeFlags.All
                                 .Subtract(_redisStore.AreBlobsSupported ? 0 : ContentMetadataStoreModeFlags.Redis | ContentMetadataStoreModeFlags.PreferRedis)
                                 .Subtract(_distributedStore.AreBlobsSupported ? 0 : ContentMetadataStoreModeFlags.Distributed | ContentMetadataStoreModeFlags.PreferDistributed);
        }
 private Task <TResult> ExecuteAsync <TResult>(
     OperationContext context,
     ContentMetadataStoreMode mode,
     ContentMetadataStoreModeFlags modeMask,
     Func <IGlobalCacheStore, Task <TResult> > executeAsync,
     [CallerMemberName] string caller = null)
     where TResult : ResultBase
 {
     return(ExecuteAsync(context, mode, modeMask, executeAsync, (store, execute) => execute(store), caller));
 }
        private static void GetFlagsAndPreferences(ContentMetadataStoreMode mode, ContentMetadataStoreModeFlags modeMask, out ContentMetadataStoreModeFlags redisFlags, out ContentMetadataStoreModeFlags distributedFlags, out bool preferRedis, out bool preferDistributed)
        {
            var modeFlags = mode.MaskFlags(modeMask);

            redisFlags       = modeFlags & ContentMetadataStoreModeFlags.Redis;
            distributedFlags = modeFlags & ContentMetadataStoreModeFlags.Distributed;
            var preference = mode.MaskFlags(ContentMetadataStoreModeFlags.PreferenceMask);

            preferRedis       = preference.HasAllFlags(ContentMetadataStoreModeFlags.PreferRedis) || distributedFlags == 0;
            preferDistributed = preference.HasAllFlags(ContentMetadataStoreModeFlags.PreferDistributed) || redisFlags == 0;
        }
        private async Task <TResult> ExecuteAsync <TResult, TState>(
            OperationContext context,
            ContentMetadataStoreMode mode,
            ContentMetadataStoreModeFlags modeMask,
            TState state,
            Func <IGlobalCacheStore, TState, Task <TResult> > executeAsync,
            string caller)
            where TResult : ResultBase
        {
            ContentMetadataStoreModeFlags redisFlags, distributedFlags;
            bool preferRedis, preferDistributed;

            GetFlagsAndPreferences(mode, modeMask, out redisFlags, out distributedFlags, out preferRedis, out preferDistributed);

            var redisTask       = MeasuredExecuteAsync(_redisStore, redisFlags, state, executeAsync);
            var distributedTask = MeasuredExecuteAsync(_distributedStore, distributedFlags, state, executeAsync);

            string extraEndMessage    = null;
            var    combinedResultTask = context.PerformOperationAsync(
                Tracer,
                async() =>
            {
                var(redisResult, distributedResult) = await WhenBothAsync(redisTask, distributedTask);
                var result      = preferDistributed ? distributedResult : redisResult;
                extraEndMessage = $"Redis={redisResult.message}, Distrib={distributedResult.message}";
                return(result.result);
            },
                caller: caller,
                extraEndMessage: r => extraEndMessage);

            if (preferRedis)
            {
                // If preferring redis, return the redis result without waiting for combined result
                return((await redisTask).result);
            }
            else if (preferDistributed)
            {
                // If preferring distributed, return the distributed result without waiting for combined result
                return((await distributedTask).result);
            }
            else
            {
                return(await combinedResultTask);
            }
        }
예제 #6
0
 public static bool HasAnyFlag(this ContentMetadataStoreModeFlags mode, ContentMetadataStoreModeFlags flags)
 {
     return((mode & flags) != 0);
 }
예제 #7
0
 public static bool HasAllFlags(this ContentMetadataStoreModeFlags mode, ContentMetadataStoreModeFlags flags)
 {
     return((mode & flags) == flags);
 }
예제 #8
0
 public static bool HasAllFlags(this ContentMetadataStoreMode mode, ContentMetadataStoreModeFlags flags)
 {
     return(mode.Flags().HasAllFlags(flags));
 }
예제 #9
0
 public static ContentMetadataStoreModeFlags Subtract(this ContentMetadataStoreModeFlags mode, ContentMetadataStoreModeFlags mask)
 {
     return(mode & (~mask));
 }