Пример #1
0
        public async Task LockAcquisitionResultContainsInformationAboutOtherProcess()
        {
            string componentName = "component1";
            var    context       = new Context(Logger);
            var    timeout       = TimeSpan.FromMilliseconds(100);

            using (var testDirectory = new DisposableDirectory(FileSystem))
                using (var lock1 = new DirectoryLock(testDirectory.Path / "lock1", FileSystem, TimeSpan.FromMinutes(30), componentName))
                    using (var lock2 = new DirectoryLock(testDirectory.Path / "lock1", FileSystem, timeout, componentName))
                    {
                        (await lock1.AcquireAsync(context)).LockAcquired.Should().BeTrue();
                        var failure = await lock2.AcquireAsync(context);

                        failure.LockAcquired.Should().BeFalse();
                        failure.Timeout.Should().Be(timeout);

                        // Fix for InMemoryFileSystem. Bug #1334691
                        if (!BuildXL.Utilities.OperatingSystemHelper.IsUnixOS && FileSystem is PassThroughFileSystem)
                        {
                            // Used to be a flaky check. Enable it because it is important.
                            failure.CompetingProcessId.HasValue.Should().BeTrue();
                            Assert.NotNull(failure.CompetingProcessName);
                        }
                    }
        }
Пример #2
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="FileSystemContentStore" /> class.
        /// </summary>
        public FileSystemContentStore(
            IAbsFileSystem fileSystem,
            IClock clock,
            AbsolutePath rootPath,
            ConfigurationModel?configurationModel,
            IDistributedLocationStore?distributedStore,
            ContentStoreSettings?settings)
        {
            Contract.Requires(fileSystem != null);
            Contract.Requires(clock != null);
            Contract.Requires(rootPath != null);

            int singleInstanceTimeoutSeconds = ContentStoreConfiguration.DefaultSingleInstanceTimeoutSeconds;

            if (configurationModel?.InProcessConfiguration != null)
            {
                // TODO: Stop using the configurationModel's SingleInstanceTimeout (bug 1365340)
                // because FileSystemContentStore doesn't respect the config file's value
                singleInstanceTimeoutSeconds = configurationModel.InProcessConfiguration.SingleInstanceTimeoutSeconds;
            }

            // FileSystemContentStore implicitly uses a null component name for compatibility with older versions' directory locks.
            _directoryLock = new DirectoryLock(rootPath, fileSystem, TimeSpan.FromSeconds(singleInstanceTimeoutSeconds));

            Store = new FileSystemContentStoreInternal(
                fileSystem,
                clock,
                rootPath,
                configurationModel,
                settings,
                distributedStore);
        }
Пример #3
0
        public void AquireTimeOut()
        {
            Console.WriteLine("Acquire Lock 1");
            var lock1 = DirectoryLock.Acquire(_directory);

            Console.WriteLine("Acquire Lock 2");
            var lock2 = DirectoryLock.Acquire(_directory, TimeSpan.FromSeconds(1));
        }
Пример #4
0
        /// <summary>
        ///     Initializes a new instance of the <see cref="SQLiteMemoizationStore"/> class.
        /// </summary>
        public SQLiteMemoizationStore
        (
            ILogger logger,
            IClock clock,
            SQLiteMemoizationStoreConfiguration config
        )
            : base(
                () => new SQLiteMemoizationStoreTracer(logger, Component),
                config.WithDatabasePath(MakeDatabasePath(config.DatabaseFilePath, DefaultDatabaseFileName))
                )
        {
            Contract.Requires(config != null);
            Contract.Requires(config.DatabaseFilePath != null);
            Contract.Requires(config.DatabaseFilePath.Parent.Path.Length > 0);
            Contract.Requires(clock != null);

            _fileSystem       = new PassThroughFileSystem(logger);
            _directoryLock    = new DirectoryLock(DatabaseFilePath.Parent, _fileSystem, TimeSpan.FromSeconds(config.SingleInstanceTimeoutSeconds), Component);
            _clock            = clock;
            _config           = config;
            _lruEnabled       = config.MaxRowCount > 0;
            _purgeCommandPool = CreatePurgeCommandPool();
            _getContentHashListCommandPool = CreateGetContentHashListCommandPool();
            _getSelectorsCommandPool       = CreateGetSelectorsCommandPool();
            _replaceCommandPool            = CreateReplaceCommandPool();
            _touchPartitionCommandPool     = CreateTouchPartitionCommandPool();
            _touchSingleCommandPool        = CreateTouchSingleCommandPool();

            // From the SQLite documentation: "If the argument N is negative,
            // then the number of cache pages is adjusted to use approximately abs(N * 1024) bytes of memory."
            var memoryCacheSize = Environment.GetEnvironmentVariable(MemoryCacheSizeEnvironmentVariable);

            if (memoryCacheSize != null)
            {
                long parsedMemoryCacheSize;
                if (!long.TryParse(memoryCacheSize, out parsedMemoryCacheSize))
                {
                    throw new ArgumentException($"Unable to parse the value [{memoryCacheSize}] of experimental environment variable {MemoryCacheSizeEnvironmentVariable}.");
                }

                _memoryCacheSize = parsedMemoryCacheSize;
            }
            else
            {
                _memoryCacheSize = null;
            }

            _warmMemoryCacheOnStartup     = Environment.GetEnvironmentVariable(WarmMemoryCacheOnStartupEnvironmentVariable) != null;
            _vacuumOnShutdown             = Environment.GetEnvironmentVariable(VacuumOnShutdownEnvironmentVariable) != null;
            _config.WaitForLruOnShutdown &= Environment.GetEnvironmentVariable(NoWaitForLruOnShutdownEnvironmentVariable) == null;
            _touchBatchSize       = GetExperimentalSetting(TouchBatchSizeEnvironmentVariableName, TouchBatchSizeDefault);
            _touchAfterInactiveMs = GetExperimentalSetting(TouchAfterInactiveMsEnvironmentVariableName, TouchAfterInactiveMsDefault);
        }
Пример #5
0
        public async Task SameBlocks(string componentName)
        {
            var context = new Context(Logger);

            using (var testDirectory = new DisposableDirectory(FileSystem))
                using (var lock1 = new DirectoryLock(testDirectory.Path / "dir1", FileSystem, TimeSpan.FromMinutes(30), componentName))
                    using (var lock2 = new DirectoryLock(testDirectory.Path / "dir1", FileSystem, TimeSpan.FromMilliseconds(100), componentName))
                    {
                        (await lock1.AcquireAsync(context)).LockAcquired.Should().BeTrue();
                        (await lock2.AcquireAsync(context)).LockAcquired.Should().BeFalse();
                    }
        }
Пример #6
0
        [InlineData("dir1", "dir2", "TestComponent1", null)]             // Different paths, one null component
        public async Task DifferentNoBlocking(string directoryName1, string directoryName2, string componentName1, string componentName2)
        {
            var context = new Context(Logger);

            using (var testDirectory = new DisposableDirectory(FileSystem))
                using (var lock1 = new DirectoryLock(testDirectory.Path / directoryName1, FileSystem, TimeSpan.FromMinutes(30), componentName1))
                    using (var lock2 = new DirectoryLock(testDirectory.Path / directoryName2, FileSystem, TimeSpan.FromMinutes(30), componentName2))
                    {
                        (await lock1.AcquireAsync(context)).LockAcquired.Should().BeTrue();
                        (await lock2.AcquireAsync(context)).LockAcquired.Should().BeTrue();
                    }
        }
Пример #7
0
        public async Task HoldingLockFileDoesNotWedge(string componentName)
        {
            var context = new Context(Logger);

            using (var testDirectory = new DisposableDirectory(FileSystem))
                using (var lockFile = new DirectoryLockFile(FileSystem, testDirectory.Path / "dir1" / $"{componentName ?? string.Empty}.lock", TimeSpan.FromMilliseconds(100)))
                    using (var lock1 = new DirectoryLock(testDirectory.Path / "dir1", FileSystem, TimeSpan.FromSeconds(1), componentName))
                        using (var lock2 = new DirectoryLock(testDirectory.Path / "dir1", FileSystem, TimeSpan.FromSeconds(1), componentName))
                        {
                            (await lockFile.AcquireAsync(context, TimeSpan.FromMinutes(1))).LockAcquired.Should().BeTrue();
                            (await lock1.AcquireAsync(context)).LockAcquired.Should().BeFalse();
                            lockFile.Dispose();
                            (await lock2.AcquireAsync(context)).LockAcquired.Should().BeTrue();
                        }
        }
Пример #8
0
        public async Task SameObjectAcquiresMultipleTimes(string componentName)
        {
            var context = new Context(Logger);

            using (var testDirectory = new DisposableDirectory(FileSystem))
                using (var lock1 = new DirectoryLock(testDirectory.Path / "dir1", FileSystem, TimeSpan.FromSeconds(1), componentName))
                {
                    var failedToAcquire = false;
                    var actionBlock     = new ActionBlock <ValueUnit>(async _ =>
                    {
                        if (!(await lock1.AcquireAsync(context)).LockAcquired)
                        {
                            failedToAcquire = true;
                        }
                    });

                    await actionBlock.PostAllAndComplete(Enumerable.Repeat(ValueUnit.Void, 5));

                    failedToAcquire.Should().BeFalse();
                }
        }
Пример #9
0
        public void Aquire()
        {
            var thread1 = new Thread(s => {
                Console.WriteLine("[Thread: {0}] Lock 1 Entry", Thread.CurrentThread.ManagedThreadId);
                using (var lock1 = DirectoryLock.Acquire(_directory, TimeSpan.FromSeconds(5))) {
                    Console.WriteLine("[Thread: {0}] Lock 1", Thread.CurrentThread.ManagedThreadId);
                    Thread.Sleep(TimeSpan.FromSeconds(10));
                }
            });

            thread1.Start();

            var thread2 = new Thread(s => {
                Console.WriteLine("[Thread: {0}] Lock 2 Entry", Thread.CurrentThread.ManagedThreadId);
                using (var lock2 = DirectoryLock.Acquire(_directory, TimeSpan.FromSeconds(5))) {
                    Console.WriteLine("[Thread: {0}] Lock 2", Thread.CurrentThread.ManagedThreadId);
                }
            });

            thread2.Start();

            Thread.Sleep(TimeSpan.FromSeconds(20));
        }
Пример #10
0
 public void SetUp()
 {
     DirectoryLock.ForceReleaseLock(_directory, true);
 }