/// <nodoc /> public LocalCacheServer( IAbsFileSystem fileSystem, ILogger logger, string scenario, Func <AbsolutePath, ICache> cacheFactory, LocalServerConfiguration localContentServerConfiguration, Capabilities capabilities = Capabilities.All) : base(logger, fileSystem, scenario, cacheFactory, localContentServerConfiguration) { // This must agree with the base class' StoresByName to avoid "missing content store" errors from Grpc, and // to make sure everything is initialized properly when we expect it to. var storesByNameAsContentStore = StoresByName.ToDictionary(kvp => kvp.Key, kvp => { var store = kvp.Value; if (store is IContentStore contentStore) { return(contentStore); } throw new ArgumentException( $"Severe cache misconfiguration: {nameof(cacheFactory)} must generate instances that are " + $"IContentStore. Instead, it generated {store.GetType()}.", nameof(cacheFactory)); }); _grpcCacheServer = new GrpcCacheServer(logger, capabilities, this, storesByNameAsContentStore, localContentServerConfiguration); }
protected override TestServiceClientContentStore CreateStore( AbsolutePath rootPath, ContentStoreConfiguration configuration, LocalServerConfiguration localContentServerConfiguration, TimeSpan?heartbeatOverride) { configuration.Write(FileSystem, rootPath); var grpcPortFileName = Guid.NewGuid().ToString(); var serviceConfiguration = new ServiceConfiguration( new Dictionary <string, AbsolutePath> { { CacheName, rootPath } }, rootPath, GracefulShutdownSeconds, PortExtensions.GetNextAvailablePort(), grpcPortFileName); return(new TestServiceClientContentStore( Logger, FileSystem, new ServiceClientContentStoreConfiguration(CacheName, null, Scenario), heartbeatOverride, serviceConfiguration, localContentServerConfiguration: localContentServerConfiguration )); }
private static LocalServerConfiguration CreateLocalServerConfiguration( LocalCasServiceSettings localCasServiceSettings, ServiceConfiguration serviceConfiguration, DistributedContentSettings distributedSettings) { serviceConfiguration.GrpcPort = localCasServiceSettings.GrpcPort; serviceConfiguration.BufferSizeForGrpcCopies = localCasServiceSettings.BufferSizeForGrpcCopies; serviceConfiguration.GzipBarrierSizeForGrpcCopies = localCasServiceSettings.GzipBarrierSizeForGrpcCopies; serviceConfiguration.ProactivePushCountLimit = localCasServiceSettings.MaxProactivePushRequestHandlers; serviceConfiguration.CopyRequestHandlingCountLimit = localCasServiceSettings.MaxCopyFromHandlers; var localContentServerConfiguration = new LocalServerConfiguration(serviceConfiguration); ApplyIfNotNull(localCasServiceSettings.UnusedSessionTimeoutMinutes, value => localContentServerConfiguration.UnusedSessionTimeout = TimeSpan.FromMinutes(value)); ApplyIfNotNull(localCasServiceSettings.UnusedSessionHeartbeatTimeoutMinutes, value => localContentServerConfiguration.UnusedSessionHeartbeatTimeout = TimeSpan.FromMinutes(value)); ApplyIfNotNull(localCasServiceSettings.GrpcCoreServerOptions, value => localContentServerConfiguration.GrpcCoreServerOptions = value); ApplyIfNotNull(localCasServiceSettings.GrpcEnvironmentOptions, value => localContentServerConfiguration.GrpcEnvironmentOptions = value); ApplyIfNotNull(distributedSettings?.UseUnsafeByteStringConstruction, value => { GrpcExtensions.UnsafeByteStringOptimizations = value; }); ApplyIfNotNull(distributedSettings?.Unsafe_DisableDeprecatedConcurrentAccessLock, value => { PassThroughFileSystem.ConcurrentAccess = new System.Threading.SemaphoreSlim(int.MaxValue); }); ApplyIfNotNull(distributedSettings?.ShutdownEvictionBeforeHibernation, value => localContentServerConfiguration.ShutdownEvictionBeforeHibernation = value); return(localContentServerConfiguration); }
private static LocalServerConfiguration CreateLocalServerConfiguration( LocalCasServiceSettings localCasServiceSettings, ServiceConfiguration serviceConfiguration, DistributedContentSettings distributedSettings) { serviceConfiguration.GrpcPort = localCasServiceSettings.GrpcPort; serviceConfiguration.BufferSizeForGrpcCopies = localCasServiceSettings.BufferSizeForGrpcCopies; serviceConfiguration.ProactivePushCountLimit = localCasServiceSettings.MaxProactivePushRequestHandlers; serviceConfiguration.CopyRequestHandlingCountLimit = localCasServiceSettings.MaxCopyFromHandlers; var localContentServerConfiguration = new LocalServerConfiguration(serviceConfiguration); ApplyIfNotNull(localCasServiceSettings.UnusedSessionTimeoutMinutes, value => localContentServerConfiguration.UnusedSessionTimeout = TimeSpan.FromMinutes(value)); ApplyIfNotNull(localCasServiceSettings.UnusedSessionHeartbeatTimeoutMinutes, value => localContentServerConfiguration.UnusedSessionHeartbeatTimeout = TimeSpan.FromMinutes(value)); ApplyIfNotNull(localCasServiceSettings.GrpcCoreServerOptions, value => localContentServerConfiguration.GrpcCoreServerOptions = value); ApplyIfNotNull(localCasServiceSettings.GrpcEnvironmentOptions, value => localContentServerConfiguration.GrpcEnvironmentOptions = value); ApplyIfNotNull(localCasServiceSettings.DoNotShutdownSessionsInUse, value => localContentServerConfiguration.DoNotShutdownSessionsInUse = value); ApplyIfNotNull(distributedSettings?.UseUnsafeByteStringConstruction, value => { GrpcExtensions.UnsafeByteStringOptimizations = value; }); ApplyIfNotNull(distributedSettings?.ShutdownEvictionBeforeHibernation, value => localContentServerConfiguration.ShutdownEvictionBeforeHibernation = value); return(localContentServerConfiguration); }
public TestInProcessServiceClientContentStore( IAbsFileSystem fileSystem, ILogger logger, string cacheName, string scenario, TimeSpan?heartbeatInterval, ServiceConfiguration serviceConfiguration, uint retryIntervalSeconds = DefaultRetryIntervalSeconds, uint retryCount = DefaultRetryCount, LocalServerConfiguration localContentServerConfiguration = null, Func <AbsolutePath, IContentStore> contentStoreFactory = null) : base(logger, fileSystem, CreateConfiguration(cacheName, scenario + TestBase.ScenarioSuffix, serviceConfiguration, retryIntervalSeconds, retryCount)) { _fileSystem = fileSystem; _logger = logger; _heartbeatInterval = heartbeatInterval; _configuration = serviceConfiguration; Server = new LocalContentServer( _fileSystem, _logger, Configuration.Scenario, contentStoreFactory ?? (path => new FileSystemContentStore(FileSystem, SystemClock.Instance, path)), localContentServerConfiguration?.OverrideServiceConfiguration(_configuration) ?? TestConfigurationHelper.CreateLocalContentServerConfiguration(_configuration)); SetThreadPoolSizes(); }
/// <nodoc /> public LocalCacheServer( IAbsFileSystem fileSystem, ILogger logger, string scenario, Func <AbsolutePath, ICache> cacheFactory, LocalServerConfiguration localContentServerConfiguration, Capabilities capabilities = Capabilities.All) : base(logger, fileSystem, scenario, cacheFactory, localContentServerConfiguration) { var storesByName = new Dictionary <string, IContentStore>(); foreach (var kvp in localContentServerConfiguration.NamedCacheRoots) { AbsolutePath cacheRootPath = kvp.Value; fileSystem.CreateDirectory(cacheRootPath); var cache = cacheFactory(cacheRootPath); Contract.Assert(cache is IContentStore, $"Attempted to setup a cache named '{kvp.Key}' that is not an {nameof(IContentStore)} at path {cacheRootPath}, type used is {cache.GetType().Name}"); storesByName.Add(kvp.Key, (IContentStore)cache); } _grpcContentServer = new GrpcContentServer(logger, capabilities, this, storesByName); _grpcCacheServer = new GrpcCacheServer(logger, this); }
protected Task RunSessionTestAsync( ImplicitPin implicitPin, Func <Context, IContentSession, Task> funcAsync, LocalServerConfiguration localContentServerConfiguration = null) { return(RunStoreTestAsync( (context, store) => RunSessionTestAsync(context, store, implicitPin, funcAsync), localContentServerConfiguration)); }
public Settings(SerialPort Port, ConfigurationReader ConfigurationReader, ConfigurationWriter ConfigurationWriter, ModuleConfiguration ModuleConfiguration, LocalServerConfiguration ServerConfiguration) { InitializeComponent(); _SerialPort = Port; _ModuleConfiguration = ModuleConfiguration; _ConfigurationReader = ConfigurationReader; _ConfigurationWriter = ConfigurationWriter; _ServerConfiguration = ServerConfiguration; }
private StartupShutdownBase CreateLocalServer(LocalServerConfiguration localServerConfiguration, DistributedContentSettings distributedSettings = null) { var resolvedCacheSettings = DistributedContentStoreFactory.ResolveCacheSettingsInPrecedenceOrder(_arguments); Func <AbsolutePath, IContentStore> contentStoreFactory = path => DistributedContentStoreFactory.CreateLocalContentStore( distributedSettings, _arguments, resolvedCacheSettings.Where(s => s.ResolvedCacheRootPath == path || s.ResolvedCacheRootPath.Path.StartsWith(path.Path, StringComparison.OrdinalIgnoreCase)).Single()); if (distributedSettings?.EnableMetadataStore == true) { _logger.Always("Creating local server with content and metadata store"); var factory = CreateDistributedContentStoreFactory(); Func <AbsolutePath, ICache> cacheFactory = path => { var distributedCache = new OneLevelCache( contentStoreFunc: () => contentStoreFactory(path), memoizationStoreFunc: () => CreateServerSideLocalMemoizationStore(path, factory), Guid.NewGuid(), passContentToMemoization: true); ICache cacheToReturn = distributedCache; #if MICROSOFT_INTERNAL if (distributedSettings.EnablePublishingCache) { cacheToReturn = new PublishingCache <OneLevelCache>( local: distributedCache, remote: new BuildCachePublishingStore(contentSource: distributedCache, _fileSystem, distributedSettings.PublishingConcurrencyLimit), Guid.NewGuid()); } #endif return(cacheToReturn); }; return(new LocalCacheServer( _fileSystem, _logger, _arguments.Configuration.LocalCasSettings.ServiceSettings.ScenarioName, cacheFactory, localServerConfiguration, capabilities: distributedSettings.EnablePublishingCache?Capabilities.All: Capabilities.AllNonPublishing)); } else { _logger.Always("Creating local server with content store only"); return(new LocalContentServer( _fileSystem, _logger, _arguments.Configuration.LocalCasSettings.ServiceSettings.ScenarioName, contentStoreFactory, localServerConfiguration)); } }
/// <inheritdoc /> public TestInProcessServiceClientCache( ILogger logger, IAbsFileSystem fileSystem, Func <AbsolutePath, ICache> contentStoreFactory, LocalServerConfiguration contentServerConfiguration, ServiceClientContentStoreConfiguration clientConfiguration) { _server = new LocalCacheServer(fileSystem, logger, clientConfiguration.Scenario, contentStoreFactory, contentServerConfiguration, Capabilities.All); _client = new ServiceClientCache(logger, fileSystem, clientConfiguration); SetThreadPoolSizes(); }
private StartupShutdownBase CreateDistributedServer(LocalServerConfiguration localServerConfiguration, DistributedContentSettings distributedSettings) { var cacheConfig = _arguments.Configuration; var factory = CreateDistributedContentStoreFactory(); // NOTE: This relies on the assumption that when creating a distributed server, // there is only one call to create a cache so we simply create the cache here and ignore path // below in factory delegates since the logic for creating path based caches is included in the // call to CreateTopLevelStore var topLevelAndPrimaryStore = factory.CreateTopLevelStore(); if (distributedSettings.EnableMetadataStore || distributedSettings.EnableDistributedCache) { Func <AbsolutePath, ICache> cacheFactory = path => { if (distributedSettings.EnableDistributedCache) { return(new DistributedOneLevelCache(topLevelAndPrimaryStore.topLevelStore, topLevelAndPrimaryStore.primaryDistributedStore, Guid.NewGuid(), passContentToMemoization: true)); } else { return(new OneLevelCache( contentStoreFunc: () => topLevelAndPrimaryStore.topLevelStore, memoizationStoreFunc: () => CreateServerSideLocalMemoizationStore(path, factory), Guid.NewGuid(), passContentToMemoization: true)); } }; // NOTE(jubayard): When generating the service configuration, we create a single named cache root in // the distributed case. This means that the factories will be called exactly once, so we will have // a single MultiplexedContentStore and MemoizationStore. The latter will be located in the last cache // root listed as per production configuration, which currently (8/27/2019) points to the SSD drives. return(new LocalCacheServer( _fileSystem, _logger, _arguments.Configuration.LocalCasSettings.ServiceSettings.ScenarioName, cacheFactory, localServerConfiguration)); } else { return(new LocalContentServer( _fileSystem, _logger, cacheConfig.LocalCasSettings.ServiceSettings.ScenarioName, path => topLevelAndPrimaryStore.topLevelStore, localServerConfiguration)); } }
/// <nodoc /> public GrpcCacheServer( ILogger logger, Capabilities serviceCapabilities, ISessionHandler <ICacheSession> sessionHandler, Dictionary <string, IContentStore> storesByName, LocalServerConfiguration localServerConfiguration = null) : base(logger, serviceCapabilities, sessionHandler, storesByName, localServerConfiguration) { _cacheSessionHandler = sessionHandler; GrpcAdapter = new MemoizationServerAdapter(this); }
/// <inheritdoc /> public TestInProcessServiceClientCache( ILogger logger, IAbsFileSystem fileSystem, Func <AbsolutePath, ICache> contentStoreFactory, LocalServerConfiguration contentServerConfiguration, ServiceClientContentStoreConfiguration clientConfiguration) { // Initialize with fewer threads for tests GrpcEnvironment.InitializeIfNeeded(3); _server = new LocalCacheService(logger, fileSystem, clientConfiguration.Scenario, contentStoreFactory, contentServerConfiguration); _client = new ServiceClientCache(logger, fileSystem, clientConfiguration); SetThreadPoolSizes(); }
public async Task HibernationDataNotLoadedIfStoreStartupFails() { const string scenario = nameof(HibernationDataNotLoadedIfStoreStartupFails); var fileName = $"{Guid.NewGuid()}.json"; var context = new Context(Logger); using (var directory = new DisposableDirectory(FileSystem)) { var rootPath = directory.Path; var contentHash = ContentHash.Random(); var pins = new List <string> { contentHash.Serialize() }; var hibernatedSessionInfo = new HibernatedContentSessionInfo(SessionId, SessionName, ImplicitPin.None, CacheName, pins, 0, Capabilities.None); var hibernatedSessions = new HibernatedSessions <HibernatedContentSessionInfo>(new List <HibernatedContentSessionInfo> { hibernatedSessionInfo }); hibernatedSessions.Write(FileSystem, rootPath, fileName); var namedCacheRoots = new Dictionary <string, AbsolutePath> { { CacheName, rootPath } }; var grpcPort = PortExtensions.GetNextAvailablePort(); var grpcPortFileName = Guid.NewGuid().ToString(); var configuration = new ServiceConfiguration(namedCacheRoots, rootPath, MaxConnections, GracefulShutdownSeconds, grpcPort, grpcPortFileName); Func <AbsolutePath, IContentStore> contentStoreFactory = (path) => new TestFailingContentStore(); var localContentServerConfiguration = new LocalServerConfiguration(configuration) { UnusedSessionHeartbeatTimeout = TimeSpan.FromSeconds(TimeoutSecs), UnusedSessionTimeout = TimeSpan.FromSeconds(TimeoutSecs * 4), RequestCallTokensPerCompletionQueue = 10, }; using (var server = new LocalContentServer(FileSystem, Logger, scenario, contentStoreFactory, localContentServerConfiguration)) { var r = await server.StartupAsync(context); r.ShouldBeError(TestFailingContentStore.FailureMessage); FileSystem.HibernatedSessionsExists(rootPath, fileName).Should().BeTrue("The hibernation data should not have been read/deleted"); } } }
public TestServiceClientContentStore( ILogger logger, IAbsFileSystem fileSystem, ServiceClientContentStoreConfiguration configuration, TimeSpan?heartbeatInterval, ServiceConfiguration serviceConfiguration, LocalServerConfiguration localContentServerConfiguration = null) : base(logger, fileSystem, configuration) { _logger = logger; _localContentServerConfiguration = localContentServerConfiguration; _serviceProcess = new ServiceProcess(_configuration, localContentServerConfiguration, configuration.Scenario, WaitForServerReadyTimeoutMs, WaitForExitTimeoutMs); _configuration = serviceConfiguration; _heartbeatInterval = heartbeatInterval; }
/// <nodoc /> public GrpcContentServer( ILogger logger, Capabilities serviceCapabilities, ISessionHandler <IContentSession> sessionHandler, Dictionary <string, IContentStore> storesByName, LocalServerConfiguration localServerConfiguration = null) { _logger = logger; _serviceCapabilities = serviceCapabilities; _sessionHandler = sessionHandler; _adapter = new ContentServerAdapter(this); _contentStoreByCacheName = storesByName; _bufferSize = localServerConfiguration?.BufferSizeForGrpcCopies ?? ContentStore.Grpc.CopyConstants.DefaultBufferSize; _gzipSizeBarrier = localServerConfiguration?.GzipBarrierSizeForGrpcCopies ?? _bufferSize * 8; _pool = new ByteArrayPool(_bufferSize); }
/// <nodoc /> public LocalCacheService( ILogger logger, IAbsFileSystem fileSystem, string scenario, Func <AbsolutePath, ICache> contentStoreFactory, LocalServerConfiguration localContentServerConfiguration, Capabilities capabilities = Capabilities.All) : base(logger, fileSystem, scenario, contentStoreFactory, localContentServerConfiguration) { var nameByDrive = new Dictionary <string, string>(); foreach (var kvp in localContentServerConfiguration.NamedCacheRoots) { nameByDrive.Add(kvp.Value.DriveLetter.ToString(), kvp.Key); } // TODO: specify the right storeByName argument _grpcContentServer = new GrpcContentServer(logger, capabilities, this, nameByDrive, new Dictionary <string, IContentStore>()); _grpcCacheServer = new GrpcCacheServer(logger, this); }
public MainWindow() { InitializeComponent(); _SerialPort = new SerialPort(); _ModuleConfiguration = new ModuleConfiguration(); _CommandProcessor = new CommandProcessingService(_SerialPort); _ConfigurationReader = new ConfigurationReader(_CommandProcessor, _ModuleConfiguration); _ConfigurationWriter = new ConfigurationWriter(_CommandProcessor, _ModuleConfiguration); _ServerConfiguration = new LocalServerConfiguration(); SettingsPage = new Settings(_SerialPort, _ConfigurationReader, _ConfigurationWriter, _ModuleConfiguration, _ServerConfiguration); BasicSetupPage = new BasicSetup(_CommandProcessor, _ModuleConfiguration); WiFiSetupPage = new WiFiSetup(_CommandProcessor, _ModuleConfiguration); TCPIPSetupPage = new TCPUDPSettings(_CommandProcessor, _ModuleConfiguration); DataLoggerPage = new DataLogging(_ServerConfiguration); RemoteTerminalPage = new RemoteTerminal(_ServerConfiguration); SettingsListViewItem.IsSelected = true; }
private static LocalServerConfiguration CreateLocalServerConfiguration( LocalCasServiceSettings localCasServiceSettings, ServiceConfiguration serviceConfiguration, DistributedContentSettings distributedSettings) { serviceConfiguration.GrpcPort = localCasServiceSettings.GrpcPort; serviceConfiguration.BufferSizeForGrpcCopies = localCasServiceSettings.BufferSizeForGrpcCopies; serviceConfiguration.GzipBarrierSizeForGrpcCopies = localCasServiceSettings.GzipBarrierSizeForGrpcCopies; serviceConfiguration.ProactivePushCountLimit = localCasServiceSettings.MaxProactivePushRequestHandlers; var localContentServerConfiguration = new LocalServerConfiguration(serviceConfiguration); ApplyIfNotNull(localCasServiceSettings.UnusedSessionTimeoutMinutes, value => localContentServerConfiguration.UnusedSessionTimeout = TimeSpan.FromMinutes(value)); ApplyIfNotNull(localCasServiceSettings.UnusedSessionHeartbeatTimeoutMinutes, value => localContentServerConfiguration.UnusedSessionHeartbeatTimeout = TimeSpan.FromMinutes(value)); ApplyIfNotNull(localCasServiceSettings.GrpcThreadPoolSize, value => localContentServerConfiguration.GrpcThreadPoolSize = value); ApplyIfNotNull(distributedSettings?.UseUnsafeByteStringConstruction, value => localContentServerConfiguration.UseUnsafeByteStringConstruction = value); ApplyIfNotNull(distributedSettings?.ShutdownEvictionBeforeHibernation, value => localContentServerConfiguration.ShutdownEvictionBeforeHibernation = value); return(localContentServerConfiguration); }
/// <inheritdoc /> protected override ICache CreateCache(DisposableDirectory testDirectory) { var backendCacheDirectory = testDirectory.Path / "Backend"; FileSystem.CreateDirectory(backendCacheDirectory); var namedCacheRoots = new Dictionary <string, AbsolutePath> { [CacheName] = backendCacheDirectory / "Root" }; var grpcPort = PortExtensions.GetNextAvailablePort(); var serverConfiguration = new LocalServerConfiguration(backendCacheDirectory, namedCacheRoots, grpcPort, FileSystem) { GrpcPortFileName = null, // Port is well known at configuration time, no need to expose it. }; var serviceClientConfiguration = new ServiceClientContentStoreConfiguration(CacheName, new ServiceClientRpcConfiguration(serverConfiguration.GrpcPort), "Scenario-" + Guid.NewGuid()); Func <AbsolutePath, ICache> contentStoreFactory = CreateBackendCache; var serviceClient = new TestInProcessServiceClientCache(Logger, FileSystem, contentStoreFactory, serverConfiguration, serviceClientConfiguration); return(serviceClient); }
private StartupShutdownBase CreateLocalServer(LocalServerConfiguration localServerConfiguration, DistributedContentSettings distributedSettings = null) { var resolvedCacheSettings = DistributedContentStoreFactory.ResolveCacheSettingsInPrecedenceOrder(_arguments); Func <AbsolutePath, IContentStore> contentStoreFactory = path => DistributedContentStoreFactory.CreateLocalContentStore( distributedSettings, _arguments, resolvedCacheSettings.Where(s => s.ResolvedCacheRootPath == path || s.ResolvedCacheRootPath.Path.StartsWith(path.Path, StringComparison.OrdinalIgnoreCase)).Single()); if (distributedSettings?.EnableMetadataStore == true) { var factory = CreateDistributedContentStoreFactory(); Func <AbsolutePath, ICache> cacheFactory = path => { return(new OneLevelCache( contentStoreFunc: () => contentStoreFactory(path), memoizationStoreFunc: () => CreateServerSideLocalMemoizationStore(path, factory), Guid.NewGuid(), passContentToMemoization: true)); }; return(new LocalCacheServer( _fileSystem, _logger, _arguments.Configuration.LocalCasSettings.ServiceSettings.ScenarioName, cacheFactory, localServerConfiguration)); } else { return(new LocalContentServer( _fileSystem, _logger, _arguments.Configuration.LocalCasSettings.ServiceSettings.ScenarioName, contentStoreFactory, localServerConfiguration)); } }
/// <nodoc /> public GrpcContentServer( ILogger logger, Capabilities serviceCapabilities, ISessionHandler <IContentSession> sessionHandler, IReadOnlyDictionary <string, IContentStore> storesByName, LocalServerConfiguration localServerConfiguration = null) { Contract.Requires(storesByName != null); _serviceCapabilities = serviceCapabilities; _contentStoreByCacheName = storesByName; _bufferSize = localServerConfiguration?.BufferSizeForGrpcCopies ?? ContentStore.Grpc.CopyConstants.DefaultBufferSize; _gzipSizeBarrier = localServerConfiguration?.GzipBarrierSizeForGrpcCopies ?? (_bufferSize * 8); _pool = new ByteArrayPool(_bufferSize); _sessionHandler = sessionHandler; _fileSystem = localServerConfiguration?.FileSystem ?? new PassThroughFileSystem(); _workingDirectory = (localServerConfiguration?.DataRootPath ?? _fileSystem.GetTempPath()) / "GrpcContentServer"; GrpcAdapter = new ContentServerAdapter(this); Logger = logger; }
protected async Task RunStoreTestAsync(Func <Context, IContentStore, Task> funcAsync, LocalServerConfiguration localContentServerConfiguration = null, TimeSpan?heartbeatOverride = null) { var context = new Context(Logger); // Using unique scenario to avoid flakiness when running the tests in parallel Scenario += Guid.NewGuid(); using (var directory = new DisposableDirectory(FileSystem)) { var config = new ContentStoreConfiguration(new MaxSizeQuota($"{DefaultMaxSize}")); using (var store = CreateStore(directory.Path, config, localContentServerConfiguration ?? TestConfigurationHelper.LocalContentServerConfiguration, heartbeatOverride)) { try { await store.StartupAsync(context).ShouldBeSuccess(); await funcAsync(context, store); } finally { await store.ShutdownAsync(context).ShouldBeSuccess(); } } } }
public async Task CacheSessionDataIsHibernated() { using var testDirectory = new DisposableDirectory(FileSystem); var cacheDirectory = testDirectory.Path / "Service"; var cacheName = "theCache"; var namedCacheRoots = new Dictionary <string, AbsolutePath> { [cacheName] = cacheDirectory / "Root" }; var grpcPort = PortExtensions.GetNextAvailablePort(); var serverConfiguration = new LocalServerConfiguration(cacheDirectory, namedCacheRoots, grpcPort, FileSystem) { GrpcPortFileName = null, // Port is well known at configuration time, no need to expose it. }; var scenario = "Default"; var server = new LocalCacheServer( FileSystem, TestGlobal.Logger, scenario, cacheFactory: CreateBlockingPublishingCache, serverConfiguration, Capabilities.All); var context = new OperationContext(new Context(Logger)); await server.StartupAsync(context).ShouldBeSuccess(); var pat = Guid.NewGuid().ToString(); var publishingConfig = new PublishingConfigDummy { PublishAsynchronously = true, }; using var clientCache = CreateClientCache(publishingConfig, pat, cacheName, grpcPort, scenario); await clientCache.StartupAsync(context).ShouldBeSuccess(); var clientSession = clientCache.CreateSession(context, name: "TheSession", ImplicitPin.None).ShouldBeSuccess().Session; await clientSession.StartupAsync(context).ShouldBeSuccess(); var piecesOfContent = 3; var putResults = await Task.WhenAll( Enumerable.Range(0, piecesOfContent) .Select(_ => clientSession.PutRandomAsync(context, HashType.Vso0, provideHash: true, size: 128, context.Token).ShouldBeSuccess())); var contentHashList = new ContentHashList(putResults.Select(r => r.ContentHash).ToArray()); var determinism = CacheDeterminism.ViaCache(CacheDeterminism.NewCacheGuid(), DateTime.UtcNow.AddDays(1)); var contentHashListwithDeterminism = new ContentHashListWithDeterminism(contentHashList, determinism); var fingerprint = new Fingerprint(ContentHash.Random().ToByteArray()); var selector = new Selector(ContentHash.Random(), output: new byte[] { 0, 42 }); var strongFingerprint = new StrongFingerprint(fingerprint, selector); var cts = new CancellationTokenSource(); // Even though publishing is blocking, this should succeed because we're publishing asynchronously. await clientSession.AddOrGetContentHashListAsync(context, strongFingerprint, contentHashListwithDeterminism, cts.Token).ShouldBeSuccess(); // Allow for the publishing operation to be registered. await Task.Delay(TimeSpan.FromSeconds(1)); // Simulate a restart. await server.ShutdownAsync(context).ShouldBeSuccess(); server.Dispose(); server = new LocalCacheServer( FileSystem, TestGlobal.Logger, scenario: scenario, cacheFactory: CreateBlockingPublishingCache, serverConfiguration, Capabilities.All); await server.StartupAsync(context).ShouldBeSuccess(); // Session should have been persisted. var sessionsAndDatas = server.GetCurrentSessions(); sessionsAndDatas.Length.Should().Be(1); var serverSession = sessionsAndDatas[0].session; var data = sessionsAndDatas[0].data; var operation = new PublishingOperation { ContentHashListWithDeterminism = contentHashListwithDeterminism, StrongFingerprint = strongFingerprint }; var operations = new[] { operation }; data.Name.Should().Be(clientSession.Name); data.Pat.Should().Be(pat); data.Capabilities.Should().Be(Capabilities.All); data.ImplicitPin.Should().Be(ImplicitPin.None); data.Pins.Should().BeEquivalentTo(new List <string>()); data.PublishingConfig.Should().BeEquivalentTo(publishingConfig); data.PendingPublishingOperations.Should().BeEquivalentTo(operations); var hibernateSession = serverSession as IHibernateCacheSession; hibernateSession.Should().NotBeNull(); var actualPending = hibernateSession.GetPendingPublishingOperations(); actualPending.Should().BeEquivalentTo(operations); await server.ShutdownAsync(context).ShouldBeSuccess(); await clientSession.ShutdownAsync(context).ShouldBeSuccess(); }
private StartupShutdownBase CreateDistributedServer(LocalServerConfiguration localServerConfiguration, DistributedContentSettings distributedSettings) { var cacheConfig = _arguments.Configuration; var factory = CreateDistributedContentStoreFactory(); // NOTE: This relies on the assumption that when creating a distributed server, // there is only one call to create a cache so we simply create the cache here and ignore path // below in factory delegates since the logic for creating path based caches is included in the // call to CreateTopLevelStore var topLevelAndPrimaryStore = factory.CreateTopLevelStore(); if (distributedSettings.EnableMetadataStore || distributedSettings.EnableDistributedCache) { _logger.Always("Creating distributed server with content and metadata store"); Func <AbsolutePath, ICache> cacheFactory = path => { if (distributedSettings.EnableDistributedCache) { var distributedCache = new DistributedOneLevelCache(topLevelAndPrimaryStore.topLevelStore, topLevelAndPrimaryStore.primaryDistributedStore, Guid.NewGuid(), passContentToMemoization: true); ICache cacheToReturn = distributedCache; #if MICROSOFT_INTERNAL if (distributedSettings.EnablePublishingCache) { cacheToReturn = new PublishingCache <DistributedOneLevelCache>( local: distributedCache, remote: new BuildCachePublishingStore(contentSource: distributedCache, _fileSystem, distributedSettings.PublishingConcurrencyLimit), Guid.NewGuid()); } #endif return(cacheToReturn); } else { return(new OneLevelCache( contentStoreFunc: () => topLevelAndPrimaryStore.topLevelStore, memoizationStoreFunc: () => CreateServerSideLocalMemoizationStore(path, factory), Guid.NewGuid(), passContentToMemoization: true)); } }; // NOTE(jubayard): When generating the service configuration, we create a single named cache root in // the distributed case. This means that the factories will be called exactly once, so we will have // a single MultiplexedContentStore and MemoizationStore. The latter will be located in the last cache // root listed as per production configuration, which currently (8/27/2019) points to the SSD drives. return(new LocalCacheServer( _fileSystem, _logger, _arguments.Configuration.LocalCasSettings.ServiceSettings.ScenarioName, cacheFactory, localServerConfiguration, capabilities: distributedSettings.EnablePublishingCache?Capabilities.All: Capabilities.AllNonPublishing, factory.GetAdditionalEndpoints())); } else { _logger.Always("Creating distributed server with content store only"); return(new LocalContentServer( _fileSystem, _logger, cacheConfig.LocalCasSettings.ServiceSettings.ScenarioName, path => topLevelAndPrimaryStore.topLevelStore, localServerConfiguration, factory.GetAdditionalEndpoints())); } }
private StartupShutdownBase CreateDistributedServer(LocalServerConfiguration localServerConfiguration, DistributedContentSettings distributedSettings) { var cacheConfig = _arguments.Configuration; var factory = CreateDistributedContentStoreFactory(); Func <AbsolutePath, MultiplexedContentStore> contentStoreFactory = path => { var drivesWithContentStore = new Dictionary <string, IContentStore>(StringComparer.OrdinalIgnoreCase); foreach (var resolvedCacheSettings in factory.OrderedResolvedCacheSettings) { _logger.Debug($"Using [{resolvedCacheSettings.Settings.CacheRootPath}]'s settings: {resolvedCacheSettings.Settings}"); drivesWithContentStore[resolvedCacheSettings.Drive] = factory.CreateContentStore(resolvedCacheSettings); } if (string.IsNullOrEmpty(cacheConfig.LocalCasSettings.PreferredCacheDrive)) { var knownDrives = string.Join(",", factory.OrderedResolvedCacheSettings.Select(cacheSetting => cacheSetting.Drive)); throw new ArgumentException($"Preferred cache drive is missing, which can indicate an invalid configuration. Known drives={knownDrives}"); } return(new MultiplexedContentStore(drivesWithContentStore, cacheConfig.LocalCasSettings.PreferredCacheDrive)); }; if (distributedSettings.EnableMetadataStore || distributedSettings.EnableDistributedCache) { Func <AbsolutePath, ICache> cacheFactory = path => { if (distributedSettings.EnableDistributedCache) { var contentStore = contentStoreFactory(path); return(new DistributedOneLevelCache(contentStore, (DistributedContentStore <AbsolutePath>)contentStore.PreferredContentStore, Guid.NewGuid(), passContentToMemoization: true)); } else { return(new OneLevelCache( contentStoreFunc: () => contentStoreFactory(path), memoizationStoreFunc: () => CreateServerSideLocalMemoizationStore(path, factory), Guid.NewGuid(), passContentToMemoization: true)); } }; // NOTE(jubayard): When generating the service configuration, we create a single named cache root in // the distributed case. This means that the factories will be called exactly once, so we will have // a single MultiplexedContentStore and MemoizationStore. The latter will be located in the last cache // root listed as per production configuration, which currently (8/27/2019) points to the SSD drives. return(new LocalCacheServer( _fileSystem, _logger, _arguments.Configuration.LocalCasSettings.ServiceSettings.ScenarioName, cacheFactory, localServerConfiguration)); } else { return(new LocalContentServer( _fileSystem, _logger, cacheConfig.LocalCasSettings.ServiceSettings.ScenarioName, contentStoreFactory, localServerConfiguration)); } }
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 }
[Trait("Category", "QTestSkip")] // Skipped public async Task RestoredSessionReleasedAfterInactivity() { const string scenario = nameof(RestoredSessionReleasedAfterInactivity); var context = new Context(Logger); using (var directory = new DisposableDirectory(FileSystem)) { var rootPath = directory.Path; var contentHash = ContentHash.Random(); var pins = new List <string> { contentHash.Serialize() }; var hibernatedSessionInfo = new HibernatedSessionInfo(SessionId, SessionName, ImplicitPin.None, CacheName, pins, DateTime.UtcNow.Ticks, Capabilities.None); var hibernatedSessions = new HibernatedSessions(new List <HibernatedSessionInfo> { hibernatedSessionInfo }); await hibernatedSessions.WriteAsync(FileSystem, rootPath); var namedCacheRoots = new Dictionary <string, AbsolutePath> { { CacheName, rootPath } }; var grpcPort = PortExtensions.GetNextAvailablePort(); var grpcPortFileName = Guid.NewGuid().ToString(); var configuration = new ServiceConfiguration(namedCacheRoots, rootPath, MaxConnections, GracefulShutdownSeconds, grpcPort, grpcPortFileName); var storeConfig = ContentStoreConfiguration.CreateWithMaxSizeQuotaMB(1); Func <AbsolutePath, IContentStore> contentStoreFactory = (path) => new FileSystemContentStore( FileSystem, SystemClock.Instance, directory.Path, new ConfigurationModel(storeConfig)); var localContentServerConfiguration = new LocalServerConfiguration(configuration) { UnusedSessionHeartbeatTimeout = TimeSpan.FromSeconds(TimeoutSecs), RequestCallTokensPerCompletionQueue = 10, }; using (var server = new LocalContentServer(FileSystem, Logger, scenario, contentStoreFactory, localContentServerConfiguration)) { var r1 = await server.StartupAsync(context); r1.ShouldBeSuccess(); var beforeIds = server.GetSessionIds(); beforeIds.Should().Contain(SessionId); // Wait one period to ensure that it times out, another to ensure that the checker finds it, and another to give it time to release it. await Task.Delay(TimeSpan.FromSeconds(TimeoutSecs * 3)); var afterIds = server.GetSessionIds(); afterIds.Count.Should().Be(0); var r2 = await server.ShutdownAsync(context); r2.ShouldBeSuccess(); } } }
private (LocalContentServer, LocalCacheServer) CreateLocalServer(LocalServerConfiguration localServerConfiguration, DistributedContentSettings distributedSettings = null) { Func <AbsolutePath, IContentStore> contentStoreFactory = path => ContentStoreFactory.CreateContentStore(_fileSystem, path, evictionAnnouncer: null, distributedEvictionSettings: default, contentStoreSettings: default, trimBulkAsync: null);
protected abstract T CreateStore(AbsolutePath rootPath, ContentStoreConfiguration configuration, LocalServerConfiguration localContentServerConfiguration, TimeSpan?heartbeatOverride);