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);
        }
Exemple #2
0
        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;
        }