public DistributedContentStoreFactory(DistributedCacheServiceArguments arguments) { _logger = arguments.Logger; _arguments = arguments; _distributedSettings = arguments.Configuration.DistributedContentSettings; _keySpace = string.IsNullOrWhiteSpace(_arguments.Keyspace) ? ContentLocationStoreFactory.DefaultKeySpace : _arguments.Keyspace; _fileSystem = new PassThroughFileSystem(_logger); _secretRetriever = new DistributedCacheSecretRetriever(arguments); var bandwidthCheckedCopier = new BandwidthCheckedCopier(_arguments.Copier, BandwidthChecker.Configuration.FromDistributedContentSettings(_distributedSettings)); _orderedResolvedCacheSettings = ResolveCacheSettingsInPrecedenceOrder(arguments); Contract.Assert(_orderedResolvedCacheSettings.Count != 0); RedisContentLocationStoreConfiguration = CreateRedisConfiguration(); _distributedContentStoreSettings = CreateDistributedStoreSettings(_arguments, RedisContentLocationStoreConfiguration); _copier = new DistributedContentCopier <AbsolutePath>( _distributedContentStoreSettings, _fileSystem, fileCopier: bandwidthCheckedCopier, fileExistenceChecker: _arguments.Copier, _arguments.CopyRequester, _arguments.PathTransformer, _arguments.Overrides.Clock ); _redisMemoizationStoreFactory = new Lazy <RedisMemoizationStoreFactory>(() => CreateRedisCacheFactory()); }
public DistributedContentStoreFactory(DistributedCacheServiceArguments arguments) { _logger = arguments.Logger; _arguments = arguments; _distributedSettings = arguments.Configuration.DistributedContentSettings; _keySpace = string.IsNullOrWhiteSpace(_arguments.Keyspace) ? ContentLocationStoreFactory.DefaultKeySpace : _arguments.Keyspace; _fileSystem = arguments.FileSystem; _secretRetriever = new DistributedCacheSecretRetriever(arguments); _orderedResolvedCacheSettings = ResolveCacheSettingsInPrecedenceOrder(arguments); Contract.Assert(_orderedResolvedCacheSettings.Count != 0); RedisContentLocationStoreConfiguration = CreateRedisConfiguration(); _distributedContentStoreSettings = CreateDistributedStoreSettings(_arguments, RedisContentLocationStoreConfiguration); _copier = new DistributedContentCopier( _distributedContentStoreSettings, _fileSystem, fileCopier: _arguments.Copier, copyRequester: _arguments.CopyRequester, _arguments.Overrides.Clock, _logger ); _redisMemoizationStoreFactory = new Lazy <RedisMemoizationStoreFactory>(() => CreateRedisCacheFactory()); }
protected override IContentStore CreateFromArguments(DistributedCacheServiceArguments arguments) { var factory = new DistributedContentStoreFactory(arguments); var topLevelStore = factory.CreateTopLevelStore().topLevelStore; return(topLevelStore); }
private static DistributedContentStoreSettings CreateDistributedStoreSettings( DistributedCacheServiceArguments arguments, RedisContentLocationStoreConfiguration redisContentLocationStoreConfiguration) { var distributedSettings = arguments.Configuration.DistributedContentSettings; PinConfiguration pinConfiguration = new PinConfiguration(); if (distributedSettings.IsPinBetterEnabled) { ApplyIfNotNull(distributedSettings.PinMinUnverifiedCount, v => pinConfiguration.PinMinUnverifiedCount = v); ApplyIfNotNull(distributedSettings.StartCopyWhenPinMinUnverifiedCountThreshold, v => pinConfiguration.StartCopyWhenPinMinUnverifiedCountThreshold = v); ApplyIfNotNull(distributedSettings.MaxIOOperations, v => pinConfiguration.MaxIOOperations = v); } var distributedContentStoreSettings = new DistributedContentStoreSettings() { TrustedHashFileSizeBoundary = distributedSettings.TrustedHashFileSizeBoundary, ParallelHashingFileSizeBoundary = distributedSettings.ParallelHashingFileSizeBoundary, MaxConcurrentCopyOperations = distributedSettings.MaxConcurrentCopyOperations, PinConfiguration = pinConfiguration, RetryIntervalForCopies = distributedSettings.RetryIntervalForCopies, MaxRetryCount = distributedSettings.MaxRetryCount, TimeoutForProactiveCopies = TimeSpan.FromMinutes(distributedSettings.TimeoutForProactiveCopiesMinutes), ProactiveCopyMode = (ProactiveCopyMode)Enum.Parse(typeof(ProactiveCopyMode), distributedSettings.ProactiveCopyMode), PushProactiveCopies = distributedSettings.PushProactiveCopies, ProactiveCopyOnPut = distributedSettings.ProactiveCopyOnPut, ProactiveCopyOnPin = distributedSettings.ProactiveCopyOnPin, ProactiveCopyUsePreferredLocations = distributedSettings.ProactiveCopyUsePreferredLocations, MaxConcurrentProactiveCopyOperations = distributedSettings.MaxConcurrentProactiveCopyOperations, ProactiveCopyLocationsThreshold = distributedSettings.ProactiveCopyLocationsThreshold, ProactiveCopyRejectOldContent = distributedSettings.ProactiveCopyRejectOldContent, ReplicaCreditInMinutes = distributedSettings.IsDistributedEvictionEnabled ? distributedSettings.ReplicaCreditInMinutes : null, EnableRepairHandling = distributedSettings.IsRepairHandlingEnabled, LocationStoreBatchSize = distributedSettings.RedisBatchPageSize, RestrictedCopyReplicaCount = distributedSettings.RestrictedCopyReplicaCount, CopyAttemptsWithRestrictedReplicas = distributedSettings.CopyAttemptsWithRestrictedReplicas, AreBlobsSupported = redisContentLocationStoreConfiguration.AreBlobsSupported, MaxBlobSize = redisContentLocationStoreConfiguration.MaxBlobSize, DelayForProactiveReplication = TimeSpan.FromSeconds(distributedSettings.ProactiveReplicationDelaySeconds), ProactiveReplicationCopyLimit = distributedSettings.ProactiveReplicationCopyLimit, EnableProactiveReplication = distributedSettings.EnableProactiveReplication, TraceProactiveCopy = distributedSettings.TraceProactiveCopy, ProactiveCopyGetBulkBatchSize = distributedSettings.ProactiveCopyGetBulkBatchSize, ProactiveCopyGetBulkInterval = TimeSpan.FromSeconds(distributedSettings.ProactiveCopyGetBulkIntervalSeconds) }; if (distributedSettings.EnableProactiveReplication && redisContentLocationStoreConfiguration.Checkpoint != null) { distributedContentStoreSettings.ProactiveReplicationInterval = redisContentLocationStoreConfiguration.Checkpoint.RestoreCheckpointInterval; } ApplyIfNotNull(distributedSettings.MaximumConcurrentPutAndPlaceFileOperations, v => distributedContentStoreSettings.MaximumConcurrentPutAndPlaceFileOperations = v); arguments.Overrides.Override(distributedContentStoreSettings); ConfigurationPrinter.TraceConfiguration(distributedContentStoreSettings, arguments.Logger); return(distributedContentStoreSettings); }
internal static IContentStore CreateLocalContentStore( DistributedContentSettings settings, DistributedCacheServiceArguments arguments, ResolvedNamedCacheSettings resolvedSettings, IDistributedLocationStore distributedStore = null) { settings = settings ?? DistributedContentSettings.CreateDisabled(); var contentStoreSettings = FromDistributedSettings(settings); ConfigurationModel configurationModel = new ConfigurationModel(new ContentStoreConfiguration(new MaxSizeQuota(resolvedSettings.Settings.CacheSizeQuotaString))); var localStore = ContentStoreFactory.CreateContentStore(arguments.FileSystem, resolvedSettings.ResolvedCacheRootPath, contentStoreSettings: contentStoreSettings, distributedStore: distributedStore, configurationModel: configurationModel); if (settings.BackingGrpcPort != null) { var backingStore = new ServiceClientContentStore( arguments.Logger, arguments.FileSystem, resolvedSettings.Name, new ServiceClientRpcConfiguration(settings.BackingGrpcPort.Value), arguments.Configuration.LocalCasSettings.CasClientSettings.RetryIntervalSecondsOnFailServiceCalls, arguments.Configuration.LocalCasSettings.CasClientSettings.RetryCountOnFailServiceCalls, scenario: settings.BackingScenario); return(new MultiLevelContentStore(localStore, backingStore)); } return(localStore); }
protected override DistributedCacheServiceArguments ModifyArguments(DistributedCacheServiceArguments arguments) { var dcs = arguments.Configuration.DistributedContentSettings; dcs.EnableDistributedCache = true; return(base.ModifyArguments(arguments)); }
public DistributedCacheSecretRetriever(DistributedCacheServiceArguments arguments) { _distributedSettings = arguments.Configuration.DistributedContentSettings; _loggingConfiguration = arguments.LoggingSettings?.Configuration; _logger = arguments.Logger; _host = arguments.Host; _secrets = new Lazy <Task <Result <RetrievedSecrets> > >(TryGetSecretsAsync); }
public CacheServerFactory(DistributedCacheServiceArguments arguments) { _arguments = arguments; _logger = arguments.Logger; // Enable POSIX delete to ensure that files are removed even when there are open handles PassThroughFileSystem.EnablePosixDelete(); _fileSystem = new PassThroughFileSystem(_logger); }
public DistributedContentStoreFactory(DistributedCacheServiceArguments arguments) { _logger = arguments.Logger; _arguments = arguments; _redisContentSecretNames = arguments.Configuration.DistributedContentSettings.GetRedisConnectionSecretNames(arguments.HostInfo.StampId); _distributedSettings = arguments.Configuration.DistributedContentSettings; _keySpace = string.IsNullOrWhiteSpace(_arguments.Keyspace) ? RedisContentLocationStoreFactory.DefaultKeySpace : _arguments.Keyspace; _fileSystem = new PassThroughFileSystem(_logger); _secretRetriever = new DistributedCacheSecretRetriever(arguments); }
public DistributedContentStoreFactory( DistributedCacheServiceArguments arguments, RedisContentSecretNames redisContentSecretNames) { _logger = arguments.Logger; _arguments = arguments; _redisContentSecretNames = redisContentSecretNames; _distributedSettings = arguments.Configuration.DistributedContentSettings; _keySpace = string.IsNullOrWhiteSpace(_arguments.Keyspace) ? RedisContentLocationStoreFactory.DefaultKeySpace : _arguments.Keyspace; _fileSystem = new PassThroughFileSystem(_logger); }
protected override ICache CreateFromArguments(DistributedCacheServiceArguments arguments) { var factory = new DistributedContentStoreFactory(arguments); var store = factory.CreateTopLevelStore().topLevelStore; return(new DistributedOneLevelCache( store, factory.Services.ContentLocationStoreServices.Instance, Guid.NewGuid(), passContentToMemoization: false)); }
protected override TestServerProvider CreateStore(Context context, DistributedCacheServiceArguments arguments) { // Need to enable ASP.Net Core GRPC arguments.Configuration.DistributedContentSettings.EnableAspNetCoreGrpc = true; var server = new TestCacheServerWrapper(Host, arguments); return(new TestServerProvider(server, new Func <IContentStore>(() => { return server.Host.Store.Task.Result; }))); }
static Result <CacheServiceWrapperConfiguration> tryCreateConfiguration(DistributedCacheServiceArguments configuration) { var outOfProcSettings = configuration.Configuration.DistributedContentSettings.OutOfProcCacheSettings; if (outOfProcSettings is null) { return(Result.FromErrorMessage <CacheServiceWrapperConfiguration>($"{nameof(configuration.Configuration.DistributedContentSettings.OutOfProcCacheSettings)} should not be null.")); } if (outOfProcSettings.Executable is null) { return(Result.FromErrorMessage <CacheServiceWrapperConfiguration>($"{nameof(outOfProcSettings.Executable)} is null.")); } if (!File.Exists(outOfProcSettings.Executable)) { // This is not a bullet proof check, but if the executable is not found we should not even trying to create an out of proc cache service. return(Result.FromErrorMessage <CacheServiceWrapperConfiguration>($"the executable is not found at '{outOfProcSettings.Executable}'.")); } if (outOfProcSettings.CacheConfigPath is null) { return(Result.FromErrorMessage <CacheServiceWrapperConfiguration>($"{nameof(outOfProcSettings.CacheConfigPath)} is null.")); } if (!File.Exists(outOfProcSettings.CacheConfigPath)) { // This is not a bullet proof check, but if the executable is not found we should not even trying to create an out of proc cache service. return(Result.FromErrorMessage <CacheServiceWrapperConfiguration>($"the cache configuration is not found at '{outOfProcSettings.CacheConfigPath}'.")); } // The next layout should be in sync with CloudBuild. AbsolutePath executable = getExecutingPath() / outOfProcSettings.Executable; var workingDirectory = getRootPath(configuration.Configuration); var hostParameters = HostParameters.FromTelemetryProvider(configuration.TelemetryFieldsProvider); var resultingConfiguration = new CacheServiceWrapperConfiguration( serviceId: "OutOfProcCache", executable: executable, workingDirectory: workingDirectory, hostParameters: hostParameters, cacheConfigPath: new AbsolutePath(outOfProcSettings.CacheConfigPath), // DataRootPath is set in CloudBuild and we need to propagate this configuration to the launched process. dataRootPath: new AbsolutePath(configuration.Configuration.DataRootPath), useInterProcSecretsCommunication: outOfProcSettings.UseInterProcSecretsCommunication); outOfProcSettings.ServiceLifetimePollingIntervalSeconds.ApplyIfNotNull(v => resultingConfiguration.ServiceLifetimePollingInterval = TimeSpan.FromSeconds(v)); outOfProcSettings.ShutdownTimeoutSeconds.ApplyIfNotNull(v => resultingConfiguration.ShutdownTimeout = TimeSpan.FromSeconds(v)); return(resultingConfiguration); }
private string[] CreateCommandLine(DistributedCacheServiceArguments arguments) { var configurationText = DeploymentUtilities.JsonSerialize(arguments.Configuration); var configurationPath = Path.Combine(arguments.DataRootPath, "ServerCacheConfiguration.json"); Directory.CreateDirectory(arguments.DataRootPath); File.WriteAllText(configurationPath, configurationText); return(new[] { "--cacheconfigurationPath", configurationPath }); }
public TestCacheServerWrapper(TestHost testHost, DistributedCacheServiceArguments arguments) { string[] commandLineArguments = CreateCommandLine(arguments); var hostParameters = HostParameters.FromEnvironment(); var hostInfo = new HostInfo(hostParameters.Stamp, hostParameters.Ring, new List <string>()); var serviceHost = new CacheServiceStartup.ServiceHost( new string[0], arguments.Configuration, hostParameters, new Context(TestGlobal.Logger)); Host = new TestServiceHost(testHost, serviceHost); var _ = arguments.Cancellation.Register(() => Host.StartupCompletedSignal.TrySetCanceled()); RunInBackground("RunCacheService", async context => { using (var cts = CancellationTokenSource.CreateLinkedTokenSource(context.Token, arguments.Cancellation)) { arguments = arguments with { Host = Host, Cancellation = cts.Token }; await DistributedCacheServiceFacade.RunAsync(arguments); Assert.True(cts.IsCancellationRequested, "Cache service task shutdown prematurely"); } return(BoolResult.Success); }, fireAndForget: false); }
public static async Task <Result <CacheServiceWrapper> > CreateAsync(DistributedCacheServiceArguments configuration) { // Validating the cache configuration var wrapperConfiguration = tryCreateConfiguration(configuration); if (!wrapperConfiguration.Succeeded) { const string BaseError = "Can't start cache service as a separate process because"; return(Result.FromErrorMessage <CacheServiceWrapper>($"{BaseError} {wrapperConfiguration.ErrorMessage}")); } // Obtaining the secrets and creating a wrapper. var serviceLifetimeManager = new ServiceLifetimeManager(wrapperConfiguration.Value.WorkingDirectory, wrapperConfiguration.Value.ServiceLifetimePollingInterval); var secretsRetriever = new DistributedCacheSecretRetriever(configuration); var secrets = await secretsRetriever.TryRetrieveSecretsAsync(); if (!secrets.Succeeded) { return(new Result <CacheServiceWrapper>(secrets)); } return(Result.Success(new CacheServiceWrapper(wrapperConfiguration.Value, serviceLifetimeManager, secrets.Value)));
protected abstract TStore CreateFromArguments(DistributedCacheServiceArguments arguments);
public ContentServerFactory(DistributedCacheServiceArguments arguments) { _arguments = arguments; _logger = arguments.Logger; _fileSystem = new PassThroughFileSystem(_logger); }
internal void Service ( [Description("Cache names")] string[] names, [Description("Cache root paths")] string[] paths, [DefaultValue(DefaultMaxConnections), Description(MaxConnectionsDescription)] uint maxConnections, [DefaultValue(DefaultGracefulShutdownSeconds), Description(GracefulShutdownSecondsDescription)] uint gracefulShutdownSeconds, [DefaultValue(ServiceConfiguration.GrpcDisabledPort), Description(GrpcPortDescription)] int grpcPort, [Description("Name of the memory mapped file used to share GRPC port. 'CASaaS GRPC port' if not specified.")] string grpcPortFileName, [DefaultValue(null), Description("Writable directory for service operations (use CWD if null)")] string dataRootPath, [DefaultValue(null), Description("Duration of inactivity after which a session will be timed out.")] double?unusedSessionTimeoutSeconds, [DefaultValue(null), Description("Duration of inactivity after which a session with a heartbeat will be timed out.")] double?unusedSessionHeartbeatTimeoutSeconds, [DefaultValue(false), Description("Stop running service")] bool stop, [DefaultValue(Constants.OneMB), Description("Max size quota in MB")] int maxSizeQuotaMB ) { Initialize(); if (stop) { IpcUtilities.SetShutdown(_scenario); return; } if (names == null || paths == null) { throw new CacheException("At least one cache name/path is required."); } if (names.Length != paths.Length) { throw new CacheException("Mismatching lengths of names/paths arguments."); } var caches = new Dictionary <string, string>(); for (var i = 0; i < names.Length; i++) { caches.Add(names[i], paths[i]); } var serverDataRootPath = !string.IsNullOrWhiteSpace(dataRootPath) ? new AbsolutePath(dataRootPath) : new AbsolutePath(Environment.CurrentDirectory); var cancellationTokenSource = new CancellationTokenSource(); #if !FEATURE_CORECLR var configuration = new ServiceConfiguration(caches, serverDataRootPath, maxConnections, gracefulShutdownSeconds, grpcPort, grpcPortFileName); if (!configuration.IsValid) { throw new CacheException($"Invalid service configuration, error=[{configuration.Error}]"); } var localContentServerConfiguration = new LocalServerConfiguration(configuration); if (unusedSessionTimeoutSeconds != null) { localContentServerConfiguration.UnusedSessionTimeout = TimeSpan.FromSeconds(unusedSessionTimeoutSeconds.Value); } if (unusedSessionHeartbeatTimeoutSeconds != null) { localContentServerConfiguration.UnusedSessionHeartbeatTimeout = TimeSpan.FromSeconds(unusedSessionHeartbeatTimeoutSeconds.Value); } if (_scenario != null) { _logger.Debug($"scenario=[{_scenario}]"); } var exitSignal = new ManualResetEvent(false); Console.CancelKeyPress += (sender, args) => { exitSignal.Set(); args.Cancel = true; }; using (var exitEvent = IpcUtilities.GetShutdownWaitHandle(_scenario)) { var server = new LocalContentServer( _fileSystem, _logger, _scenario, path => new FileSystemContentStore( _fileSystem, SystemClock.Instance, path, new ConfigurationModel(inProcessConfiguration: ContentStoreConfiguration.CreateWithMaxSizeQuotaMB((uint)maxSizeQuotaMB))), localContentServerConfiguration); using (server) { var context = new Context(_logger); try { var result = server.StartupAsync(context).Result; if (!result.Succeeded) { throw new CacheException(result.ErrorMessage); } int completedIndex = WaitHandle.WaitAny(new WaitHandle[] { exitSignal, exitEvent }); var source = completedIndex == 0 ? "control-C" : "exit event"; _tracer.Always(context, $"Shutdown by {source}."); } finally { var result = server.ShutdownAsync(context).Result; if (!result.Succeeded) { _tracer.Warning(context, $"Failed to shutdown store: {result.ErrorMessage}"); } } } } #else Console.CancelKeyPress += (sender, args) => { cancellationTokenSource.Cancel(); args.Cancel = true; }; var localCasSettings = LocalCasSettings.Default(maxSizeQuotaMB, serverDataRootPath.Path, names[0], (uint)grpcPort); var distributedContentSettings = DistributedContentSettings.CreateDisabled(); var distributedCacheServiceConfiguration = new DistributedCacheServiceConfiguration(localCasSettings, distributedContentSettings); // Ensure the computed keyspace is computed based on the hostInfo's StampId distributedCacheServiceConfiguration.UseStampBasedIsolation = false; var distributedCacheServiceArguments = new DistributedCacheServiceArguments( logger: _logger, copier: null, pathTransformer: null, host: new EnvironmentVariableHost(), hostInfo: new HostInfo(null, null, new List <string>()), cancellation: cancellationTokenSource.Token, dataRootPath: serverDataRootPath.Path, configuration: distributedCacheServiceConfiguration, keyspace: null); DistributedCacheServiceFacade.RunAsync(distributedCacheServiceArguments).GetAwaiter().GetResult(); // Because the facade completes immediately and named wait handles don't exist in CORECLR, // completion here is gated on Control+C. In the future, this can be redone with another option, // such as a MemoryMappedFile or GRPC heartbeat. This is just intended to be functional. cancellationTokenSource.Token.WaitHandle.WaitOne(); #endif }
internal void Service ( [Description("Cache names")] string[] names, [Description("Cache root paths")] string[] paths, [DefaultValue(DefaultMaxConnections), Description(MaxConnectionsDescription)] uint maxConnections, [DefaultValue(DefaultGracefulShutdownSeconds), Description(GracefulShutdownSecondsDescription)] uint gracefulShutdownSeconds, [DefaultValue(ServiceConfiguration.GrpcDisabledPort), Description(GrpcPortDescription)] uint grpcPort, [Description("Name of the memory mapped file used to share GRPC port. 'CASaaS GRPC port' if not specified.")] string grpcPortFileName, [DefaultValue(null), Description("Writable directory for service operations (use CWD if null)")] string dataRootPath, [DefaultValue(null), Description("Duration of inactivity after which a session will be timed out.")] double?unusedSessionTimeoutSeconds, [DefaultValue(null), Description("Duration of inactivity after which a session with a heartbeat will be timed out.")] double?unusedSessionHeartbeatTimeoutSeconds, [DefaultValue(false), Description("Stop running service")] bool stop, [DefaultValue(Constants.OneGBInMB), Description("Max size quota in MB")] int maxSizeQuotaMB, [DefaultValue(ServiceConfiguration.GrpcDisabledPort), Description(RemoteGrpcPortDescription)] uint backingGrpcPort, [DefaultValue(null), Description("Name of scenario for backing CAS service")] string backingScenario, [DefaultValue("None"), Description("Ring Id. Used only for telemetry.")] string ringId, [DefaultValue("None"), Description("Stamp Id. Used only for telemetry.")] string stampId, [DefaultValue(null), Description("nLog configuration path. If empty, it is disabled")] string nLogConfigurationPath, [DefaultValue(null), Description("Whether to use Azure Blob logging or not")] string nLogToBlobStorageSecretName, [DefaultValue(null), Description("If using Azure Blob logging, where to temporarily store logs")] string nLogToBlobStorageWorkspacePath, [DefaultValue(false), Description("Enable metadata")] bool enableMetadata ) { Initialize(); if (stop) { IpcUtilities.SetShutdown(_scenario); return; } if (names == null || paths == null) { throw new CacheException("At least one cache name/path is required."); } if (names.Length != paths.Length) { throw new CacheException("Mismatching lengths of names/paths arguments."); } var serverDataRootPath = !string.IsNullOrWhiteSpace(dataRootPath) ? new AbsolutePath(dataRootPath) : new AbsolutePath(Environment.CurrentDirectory); var cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(_cancellationToken); if (_scenario != null) { _logger.Debug($"scenario=[{_scenario}]"); } using var exitEvent = GetExitEvent(); var localCasSettings = LocalCasSettings.Default(maxSizeQuotaMB, paths[0], names[0], grpcPort, grpcPortFileName); for (int i = 1; i < names.Length; i++) { localCasSettings.AddNamedCache(names[i], paths[i]); } localCasSettings.ServiceSettings.ScenarioName = _scenario; if (unusedSessionTimeoutSeconds != null) { localCasSettings.ServiceSettings.UnusedSessionTimeoutMinutes = TimeSpan.FromSeconds(unusedSessionTimeoutSeconds.Value).TotalMinutes; } if (unusedSessionHeartbeatTimeoutSeconds != null) { localCasSettings.ServiceSettings.UnusedSessionHeartbeatTimeoutMinutes = TimeSpan.FromSeconds(unusedSessionHeartbeatTimeoutSeconds.Value).TotalMinutes; } var distributedContentSettings = DistributedContentSettings.CreateDisabled(); if (backingGrpcPort != ServiceConfiguration.GrpcDisabledPort) { distributedContentSettings.BackingGrpcPort = (int)backingGrpcPort; distributedContentSettings.BackingScenario = backingScenario; } if (enableMetadata) { distributedContentSettings.EnableMetadataStore = true; } LoggingSettings loggingSettings = null; if (!string.IsNullOrEmpty(nLogConfigurationPath)) { loggingSettings = new LoggingSettings() { NLogConfigurationPath = nLogConfigurationPath, Configuration = new AzureBlobStorageLogPublicConfiguration() { SecretName = nLogToBlobStorageSecretName, WorkspaceFolderPath = nLogToBlobStorageWorkspacePath, } }; } var distributedCacheServiceConfiguration = new DistributedCacheServiceConfiguration(localCasSettings, distributedContentSettings, loggingSettings); // Ensure the computed keyspace is computed based on the hostInfo's StampId distributedCacheServiceConfiguration.UseStampBasedIsolation = false; var distributedCacheServiceArguments = new DistributedCacheServiceArguments( logger: _logger, copier: new DistributedCopier(), copyRequester: null, host: new EnvironmentVariableHost(), hostInfo: new HostInfo(null, null, new List <string>()), cancellation: cancellationTokenSource.Token, dataRootPath: serverDataRootPath.Path, configuration: distributedCacheServiceConfiguration, keyspace: null) { TelemetryFieldsProvider = new TelemetryFieldsProvider(ringId, stampId, serviceName: "Service"), }; var runTask = Task.Run(() => DistributedCacheServiceFacade.RunAsync(distributedCacheServiceArguments)); // Because the facade completes immediately and named wait handles don't exist in CORECLR, // completion here is gated on Control+C. In the future, this can be redone with another option, // such as a MemoryMappedFile or GRPC heartbeat. This is just intended to be functional. int completedIndex = WaitHandle.WaitAny(new WaitHandle[] { cancellationTokenSource.Token.WaitHandle, exitEvent }); var source = completedIndex == 0 ? "control-C" : "exit event"; _logger.Always($"Shutdown by {source}."); if (completedIndex == 1) { cancellationTokenSource.Cancel(); } runTask.GetAwaiter().GetResult(); }
private static DistributedContentStoreSettings CreateDistributedStoreSettings( DistributedCacheServiceArguments arguments, RedisContentLocationStoreConfiguration redisContentLocationStoreConfiguration) { var distributedSettings = arguments.Configuration.DistributedContentSettings; ContentAvailabilityGuarantee contentAvailabilityGuarantee; if (string.IsNullOrEmpty(distributedSettings.ContentAvailabilityGuarantee)) { contentAvailabilityGuarantee = ContentAvailabilityGuarantee.FileRecordsExist; } else if (!Enum.TryParse(distributedSettings.ContentAvailabilityGuarantee, true, out contentAvailabilityGuarantee)) { throw new ArgumentException($"Unable to parse {nameof(distributedSettings.ContentAvailabilityGuarantee)}: [{distributedSettings.ContentAvailabilityGuarantee}]"); } PinConfiguration pinConfiguration = null; if (distributedSettings.IsPinBetterEnabled) { pinConfiguration = new PinConfiguration(); ApplyIfNotNull(distributedSettings.PinRisk, v => pinConfiguration.PinRisk = v); ApplyIfNotNull(distributedSettings.PinMinUnverifiedCount, v => pinConfiguration.PinMinUnverifiedCount = v); ApplyIfNotNull(distributedSettings.MachineRisk, v => pinConfiguration.MachineRisk = v); ApplyIfNotNull(distributedSettings.FileRisk, v => pinConfiguration.FileRisk = v); ApplyIfNotNull(distributedSettings.MaxIOOperations, v => pinConfiguration.MaxIOOperations = v); pinConfiguration.IsPinCachingEnabled = distributedSettings.IsPinCachingEnabled; ApplyIfNotNull(distributedSettings.PinCacheReplicaCreditRetentionMinutes, v => pinConfiguration.PinCachePerReplicaRetentionCreditMinutes = v); ApplyIfNotNull(distributedSettings.PinCacheReplicaCreditRetentionDecay, v => pinConfiguration.PinCacheReplicaCreditRetentionFactor = v); } var contentHashBumpTime = TimeSpan.FromMinutes(distributedSettings.ContentHashBumpTimeMinutes); var lazyTouchContentHashBumpTime = distributedSettings.IsTouchEnabled ? (TimeSpan?)contentHashBumpTime : null; if (redisContentLocationStoreConfiguration.ReadMode == ContentLocationMode.LocalLocationStore) { // LocalLocationStore has its own internal notion of lazy touch/registration. We disable the lazy touch in distributed content store // because it can conflict with behavior of the local location store. lazyTouchContentHashBumpTime = null; } var distributedContentStoreSettings = new DistributedContentStoreSettings() { TrustedHashFileSizeBoundary = distributedSettings.TrustedHashFileSizeBoundary, ParallelHashingFileSizeBoundary = distributedSettings.ParallelHashingFileSizeBoundary, MaxConcurrentCopyOperations = distributedSettings.MaxConcurrentCopyOperations, PinConfiguration = pinConfiguration, RetryIntervalForCopies = distributedSettings.RetryIntervalForCopies, MaxRetryCount = distributedSettings.MaxRetryCount, TimeoutForProactiveCopies = TimeSpan.FromMinutes(distributedSettings.TimeoutForProactiveCopiesMinutes), ProactiveCopyMode = (ProactiveCopyMode)Enum.Parse(typeof(ProactiveCopyMode), distributedSettings.ProactiveCopyMode), PushProactiveCopies = distributedSettings.PushProactiveCopies, ProactiveCopyOnPut = distributedSettings.ProactiveCopyOnPut, ProactiveCopyOnPin = distributedSettings.ProactiveCopyOnPin, ProactiveCopyUsePreferredLocations = distributedSettings.ProactiveCopyUsePreferredLocations, MaxConcurrentProactiveCopyOperations = distributedSettings.MaxConcurrentProactiveCopyOperations, ProactiveCopyLocationsThreshold = distributedSettings.ProactiveCopyLocationsThreshold, ProactiveCopyRejectOldContent = distributedSettings.ProactiveCopyRejectOldContent, ReplicaCreditInMinutes = distributedSettings.IsDistributedEvictionEnabled ? distributedSettings.ReplicaCreditInMinutes : null, EnableRepairHandling = distributedSettings.IsRepairHandlingEnabled, ContentHashBumpTime = lazyTouchContentHashBumpTime, LocationStoreBatchSize = distributedSettings.RedisBatchPageSize, ContentAvailabilityGuarantee = contentAvailabilityGuarantee, PrioritizeDesignatedLocationsOnCopies = distributedSettings.PrioritizeDesignatedLocationsOnCopies, RestrictedCopyReplicaCount = distributedSettings.RestrictedCopyReplicaCount, CopyAttemptsWithRestrictedReplicas = distributedSettings.CopyAttemptsWithRestrictedReplicas, AreBlobsSupported = redisContentLocationStoreConfiguration.AreBlobsSupported, MaxBlobSize = redisContentLocationStoreConfiguration.MaxBlobSize, DelayForProactiveReplication = TimeSpan.FromSeconds(distributedSettings.ProactiveReplicationDelaySeconds), ProactiveReplicationCopyLimit = distributedSettings.ProactiveReplicationCopyLimit, EnableProactiveReplication = distributedSettings.EnableProactiveReplication, TraceProactiveCopy = distributedSettings.TraceProactiveCopy, }; if (distributedSettings.EnableProactiveReplication && redisContentLocationStoreConfiguration.Checkpoint != null) { distributedContentStoreSettings.ProactiveReplicationInterval = redisContentLocationStoreConfiguration.Checkpoint.RestoreCheckpointInterval; } ApplyIfNotNull(distributedSettings.MaximumConcurrentPutAndPlaceFileOperations, v => distributedContentStoreSettings.MaximumConcurrentPutAndPlaceFileOperations = v); arguments.Overrides.Override(distributedContentStoreSettings); ConfigurationPrinter.TraceConfiguration(distributedContentStoreSettings, arguments.Logger); return(distributedContentStoreSettings); }
internal static List <ResolvedNamedCacheSettings> ResolveCacheSettingsInPrecedenceOrder(DistributedCacheServiceArguments arguments) { var localCasSettings = arguments.Configuration.LocalCasSettings; var cacheSettingsByName = localCasSettings.CacheSettingsByCacheName; Dictionary <string, string> cacheNamesByDrive = cacheSettingsByName.ToDictionary(x => Path.GetPathRoot(x.Value.CacheRootPath), x => x.Key, StringComparer.OrdinalIgnoreCase); var result = new List <ResolvedNamedCacheSettings>(); void addCacheByName(string cacheName) { var cacheSettings = cacheSettingsByName[cacheName]; var resolvedCacheRootPath = localCasSettings.GetCacheRootPathWithScenario(cacheName); result.Add( new ResolvedNamedCacheSettings( name: cacheName, settings: cacheSettings, resolvedCacheRootPath: resolvedCacheRootPath, machineLocation: arguments.PathTransformer.GetLocalMachineLocation(resolvedCacheRootPath))); } // Add caches specified in drive preference order foreach (var drive in localCasSettings.DrivePreferenceOrder) { if (cacheNamesByDrive.TryGetValue(drive, out var cacheName)) { addCacheByName(cacheName); cacheNamesByDrive.Remove(drive); } } // Add remaining caches foreach (var cacheName in cacheNamesByDrive.Values) { addCacheByName(cacheName); } return(result); }
protected virtual DistributedCacheServiceArguments ModifyArguments(DistributedCacheServiceArguments arguments) => arguments;