public async Task <(IDatabase database, CancellationToken databaseLifetimeToken)> GetDatabaseWithKeyPrefix(Context context, string keySpace) { var connectionMultiplexer = await _connectionMultiplexer.GetValueAsync(); if (_resetConnectionMultiplexerCts.IsCancellationRequested) { using (await SemaphoreSlimToken.WaitAsync(_creationSemaphore)) { if (_resetConnectionMultiplexerCts.IsCancellationRequested) { Tracer.Debug(context, "Shutting down current connection multiplexer."); await _connectionMultiplexerShutdownFunc(connectionMultiplexer); Tracer.Debug(context, "Creating new multiplexer instance."); var newConnectionMultiplexer = await _connectionMultiplexerFactory(); connectionMultiplexer = newConnectionMultiplexer; // Using volatile operation to prevent the instruction reordering. // We really want the cts change to be the last one. Volatile.Write(ref _connectionMultiplexer, AsyncLazy <IConnectionMultiplexer> .FromResult(newConnectionMultiplexer)); // Need to change the source at the end to avoid the race condition when // another thread can see a non-canceled CancellationTokenSource // and at the end still get an old connection multiplexer. _resetConnectionMultiplexerCts = new CancellationTokenSource(); } } } return(connectionMultiplexer.GetDatabase().WithKeyPrefix(keySpace), _resetConnectionMultiplexerCts.Token); }
public TestScheduler( PipGraph graph, TestPipQueue pipQueue, PipExecutionContext context, FileContentTable fileContentTable, EngineCache cache, IConfiguration configuration, FileAccessWhitelist fileAccessWhitelist, DirectoryMembershipFingerprinterRuleSet directoryMembershipFingerprinterRules = null, ITempCleaner tempCleaner = null, PipRuntimeTimeTable runningTimeTable = null, JournalState journalState = null, PerformanceCollector performanceCollector = null, string fingerprintSalt = null, PreserveOutputsInfo?previousInputsSalt = null, IEnumerable <Pip> successfulPips = null, IEnumerable <Pip> failedPips = null, LoggingContext loggingContext = null, IIpcProvider ipcProvider = null, DirectoryTranslator directoryTranslator = null, VmInitializer vmInitializer = null, SchedulerTestHooks testHooks = null) : base(graph, pipQueue, context, fileContentTable, cache, configuration, fileAccessWhitelist, loggingContext, null, directoryMembershipFingerprinterRules, tempCleaner, AsyncLazy <PipRuntimeTimeTable> .FromResult(runningTimeTable), performanceCollector, fingerprintSalt, previousInputsSalt, ipcProvider: ipcProvider, directoryTranslator: directoryTranslator, journalState: journalState, vmInitializer: vmInitializer, testHooks: testHooks) { m_testPipQueue = pipQueue; if (successfulPips != null) { foreach (var pip in successfulPips) { Contract.Assume(pip.PipId.IsValid, "Override results must be added after the pip has been added to the scheduler"); m_overridePipResults.Add(pip.PipId, PipResultStatus.Succeeded); } } if (failedPips != null) { foreach (var pip in failedPips) { Contract.Assume(pip.PipId.IsValid, "Override results must be added after the pip has been added to the scheduler"); m_overridePipResults.Add(pip.PipId, PipResultStatus.Failed); } } m_loggingContext = loggingContext; }