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); } }
public static bool HasAnyFlag(this ContentMetadataStoreModeFlags mode, ContentMetadataStoreModeFlags flags) { return((mode & flags) != 0); }
public static bool HasAllFlags(this ContentMetadataStoreModeFlags mode, ContentMetadataStoreModeFlags flags) { return((mode & flags) == flags); }
public static bool HasAllFlags(this ContentMetadataStoreMode mode, ContentMetadataStoreModeFlags flags) { return(mode.Flags().HasAllFlags(flags)); }
public static ContentMetadataStoreModeFlags Subtract(this ContentMetadataStoreModeFlags mode, ContentMetadataStoreModeFlags mask) { return(mode & (~mask)); }