public void Can_Not_Acquire_Same_Lock_In_Same_Scope()
        {
            var lockScopePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var lockManager   = new DistributedLockManager(new FileLockProvider(lockScopePath));

            try
            {
                // Now test other scenarios while another thread holds the lock.
                using (var testLock = OtherThreadLockHelper.TryLock(this, lockManager, MultiprocessLockName, 0))
                {
                    Assert.IsNotNull(testLock, "Unable to lock the repository");

                    //now that I have the test lock, it should fail if I try to get it again.
                    Assert.Catch <LockTimeoutException>(() =>
                    {
                        using (var failedLock = lockManager.Lock(this, MultiprocessLockName, 0))
                        {
                            Assert.IsNull(failedLock, "Duplicate lock was allowed.");
                        }
                    });
                }
            }
            finally
            {
                Directory.Delete(lockScopePath);
            }
        }
コード例 #2
0
        public async Task Can_Acquire_Lock_Many_Times_Async()
        {
            var lockManager = new DistributedLockManager(GetLockProvider(DefaultLockDatabase));

            var lockIterations = 1000;

            for (var curIteration = 0; curIteration < lockIterations; curIteration++)
            {
                try
                {
                    var outerLock = lockManager.Lock(this, MultiprocessLockName, 0);

                    try
                    {
                        Assert.IsNotNull(outerLock, "Unable to acquire lock on iteration {0:N0}", curIteration);

                        //now we need to do something else async so we resume back.
                        await GratuitousWorkAsync(outerLock).ConfigureAwait(false);
                    }
                    finally
                    {
                        outerLock.Dispose();
                    }
                }
                catch (LockTimeoutException ex)
                {
                    throw new Exception("Unable to acquire the lock immediately on iteration " + curIteration, ex);
                }
            }
        }
コード例 #3
0
        public void LockRepositoryTimeout()
        {
            var lockManager = new DistributedLockManager(GetLockProvider(DefaultLockDatabase));

            using (var testLock = OtherThreadLockHelper.TryLock(this, lockManager, MultiprocessLockName, 0))
            {
                Assert.IsNotNull(testLock, "Unable to lock the repository");

                //now when we try to get it we should not, and should wait at least our timeout
                var             lockStart = DateTimeOffset.Now;
                DistributedLock timeoutLock;
                Assert.IsFalse(lockManager.TryLock(this, MultiprocessLockName, 5, out timeoutLock));
                using (timeoutLock)
                {
                    //we shouldn't have the lock
                    Assert.IsNull(timeoutLock, "Duplicate lock allowed");

                    //and we should be within a reasonable delta of our timeout.
                    var delay = DateTimeOffset.Now - lockStart;
                    Trace.Write(string.Format("Repository Timeout Requested: {0} Actual: {1}", 5, delay.TotalSeconds));
                    Assert.Greater(delay.TotalSeconds, 4.5, "Timeout happened too fast - {0} seconds", delay.TotalSeconds);
                    Assert.Less(delay.TotalSeconds, 5.5, "Timeout happened too slow - {0} seconds", delay.TotalSeconds);
                }
            }
        }
コード例 #4
0
        public ObjectPersistenceTests()
        {
            var cephOptions            = new CephOptions();
            var distributedLockManager = new DistributedLockManager(
                new InMemoryLockFactory(),
                new DistributedLockOptions {
                Expiration = TimeSpan.FromHours(1)
            });
            var sessionStorageReader = new SessionStorageReader(cephOptions, _cephS3ClientMock.Object, _memoryCache);
            var options = new DbContextOptionsBuilder <VStoreContext>()
                          .UseInMemoryDatabase(Guid.NewGuid().ToString())
                          .Options;

            _inMemoryContext          = new InMemoryContext(options);
            _objectsManagementService = new ObjectsManagementService(
                Mock.Of <ILogger <ObjectsManagementService> >(),
                new KafkaOptions(),
                _inMemoryContext,
                _templatesStorageReaderMock.Object,
                _objectsStorageReaderMock.Object,
                sessionStorageReader,
                distributedLockManager,
                _eventSender,
                new MetricsProvider());
        }
コード例 #5
0
        private void HelperThreadStart()
        {
            DistributedLockManager.LockBarrier();

            lock (m_Lock)
            {
                m_LockManager.TryLock(this, m_Name, m_Timeout, out m_RepositoryLock);

                if (m_RepositoryLock != null)
                {
                    Monitor.PulseAll(m_Lock);

                    while (m_Exiting == false)
                    {
                        Monitor.Wait(m_Lock); // Thread waits until we're told to exit.
                    }

                    m_RepositoryLock.Dispose(); // We're exiting, so it's time to release the lock!
                    m_RepositoryLock = null;
                }
                // Otherwise, we couldn't get the lock.

                m_Exited = true; // Lock is released and thread is exiting.
                Monitor.PulseAll(m_Lock);
            }
        }
        public void Can_ReEnter_Lock_On_Same_Thread()
        {
            var lockScopePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var lockManager   = new DistributedLockManager(new FileLockProvider(lockScopePath));

            try
            {
                // First test new re-entrant lock capability.
                using (var outerLock = lockManager.Lock(this, MultiprocessLockName, 0))
                {
                    Assert.IsNotNull(outerLock, "Unable to outer lock the repository");

                    // Now check that we can get the same lock on the same thread.
                    using (var middleLock = lockManager.Lock(this, MultiprocessLockName, 0))
                    {
                        Assert.IsNotNull(middleLock, "Unable to reenter the repository lock on the same thread");

                        using (var innerLock = lockManager.Lock(this, MultiprocessLockName, 0))
                        {
                            Assert.IsNotNull(innerLock, "Unable to reenter the repository lock on the same thread twice");
                        }
                    }
                }
            }
            finally
            {
                Directory.Delete(lockScopePath);
            }
        }
        public void Can_Acquire_Same_Lock_In_Different_Scope()
        {
            var firstTestRepositoryPath  = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var secondTestRepositoryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var thirdTestRepositoryPath  = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var fourthTestRepositoryPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

            var firstLockManager = new DistributedLockManager(new FileLockProvider(firstTestRepositoryPath));

            try
            {
                // Now test other scenarios while another thread holds the lock.
                using (var testLock = firstLockManager.Lock(this, MultiprocessLockName, 0))
                {
                    Assert.IsNotNull(testLock, "Unable to establish lock on first scope");

                    var secondLockManager = new DistributedLockManager(new FileLockProvider(secondTestRepositoryPath));
                    using (var secondTestLock = secondLockManager.Lock(this, MultiprocessLockName, 0))
                    {
                        Assert.IsNotNull(secondTestLock, "Unable to establish lock on second scope.");

                        var thirdLockManager = new DistributedLockManager(new FileLockProvider(thirdTestRepositoryPath));
                        using (var thirdTestLock = thirdLockManager.Lock(this, MultiprocessLockName, 0))
                        {
                            Assert.IsNotNull(thirdTestLock, "Unable to establish lock on third scope.");

                            var forthLockManager = new DistributedLockManager(new FileLockProvider(fourthTestRepositoryPath));
                            using (var fourthTestLock = forthLockManager.Lock(this, MultiprocessLockName, 0))
                            {
                                Assert.IsNotNull(fourthTestLock, "Unable to establish lock on fourth scope.");
                            }
                        }
                    }
                }
            }
            finally
            {
                //and clean up after ourselves.
                if (Directory.Exists(firstTestRepositoryPath))
                {
                    Directory.Delete(firstTestRepositoryPath, true);
                }

                if (Directory.Exists(secondTestRepositoryPath))
                {
                    Directory.Delete(secondTestRepositoryPath, true);
                }

                if (Directory.Exists(thirdTestRepositoryPath))
                {
                    Directory.Delete(thirdTestRepositoryPath, true);
                }

                if (Directory.Exists(fourthTestRepositoryPath))
                {
                    Directory.Delete(fourthTestRepositoryPath, true);
                }
            }
        }
コード例 #8
0
 private OtherThreadLockHelper(object requester, DistributedLockManager lockManager, string lockName, int timeout)
 {
     m_RepositoryLock = null;
     m_Requester      = requester;
     m_LockManager    = lockManager;
     m_Name           = lockName;
     m_Timeout        = timeout;
 }
コード例 #9
0
        private async Task <Guid> ResetAndReadLockIdAsync()
        {
            DistributedLockManager.LockBarrier();

            await Task.Delay(0); //just to force us to yield.

            return(await ReadLockIdAsync());
        }
コード例 #10
0
        static void Main(string[] args)
        {
            var configuredConnectionString = ConfigurationManager.ConnectionStrings["LockManager"];

            if (configuredConnectionString == null)
            {
                System.Console.WriteLine("No connection string configured named 'LockManager'");
                return;
            }

            var lockProvider = new SqlLockProvider(configuredConnectionString.ConnectionString);
            var lockManager  = new DistributedLockManager(lockProvider);

            System.Console.WriteLine("Configuring Test");

            var rng = new RNGCryptoServiceProvider();

            int  tasks          = 100;
            bool highContention = false;

            TimeSpan maxLockDuration;
            TimeSpan lockTimeout;
            int      maxLockNumber;

            if (highContention)
            {
                maxLockDuration = new TimeSpan(0, 0, 0, 0, 50);
                lockTimeout     = new TimeSpan(0, 1, 0);
                maxLockNumber   = tasks / 2;
            }
            else
            {
                maxLockDuration = new TimeSpan(0, 0, 0, 0, 50);
                lockTimeout     = new TimeSpan(0, 2, 00);
                maxLockNumber   = tasks * 5;
            }

            var lockingClient = new LockingClient(lockManager, rng, maxLockDuration, lockTimeout, "Session~d9a84ccf-9bef-4777-b202-a4343d35089a", maxLockNumber);

            try
            {
                lockingClient.Start(tasks);
                System.Console.WriteLine("Running Lock Test, press any key to exit");
                System.Console.ReadKey(true);

                System.Console.WriteLine("Shutting down lock test");
            }
            catch (Exception ex)
            {
                System.Console.WriteLine(ex);
            }
            finally
            {
                lockingClient.Stop();
                Thread.Sleep(new TimeSpan(0, 0, 10));
                System.Console.WriteLine("Exiting Lock Test");
            }
        }
コード例 #11
0
        public void Can_Acquire_Lock()
        {
            var lockManager = new DistributedLockManager(GetLockProvider(DefaultLockDatabase));

            using (var outerLock = lockManager.Lock(this, MultiprocessLockName, 0))
            {
                Assert.IsNotNull(outerLock, "Unable to acquire lock");
            }
        }
コード例 #12
0
 public LockingClient(DistributedLockManager lockManager, RandomNumberGenerator rng, TimeSpan maxLockDuration, TimeSpan lockTimeout, string lockPrefix, int maxLockNumber)
 {
     _lockManager       = lockManager;
     _rng               = rng;
     _maxLockDuration   = maxLockDuration;
     _lockTimeout       = lockTimeout;
     _lockPrefix        = lockPrefix;
     _maxLockNumber     = maxLockNumber;
     _defaultForeground = System.Console.ForegroundColor;
 }
コード例 #13
0
        public void Can_Acquire_Lock_With_Unsafe_Name()
        {
            var lockManager = new DistributedLockManager(GetLockProvider(DefaultLockDatabase));

            var unsafeLockName = "\"M<>\"\\a/ry/ h**ad:>> a\\/:*?\"<>| li*tt|le|| la\"mb.?";

            using (var outerLock = lockManager.Lock(this, unsafeLockName, 0))
            {
                Assert.IsNotNull(outerLock, "Unable to acquire the lock");
            }
        }
コード例 #14
0
 public TemplatesManagementService(
     VStoreContext context,
     UploadFileOptions uploadFileOptions,
     ITemplatesStorageReader templatesStorageReader,
     DistributedLockManager distributedLockManager)
 {
     _context = context;
     _templatesStorageReader = templatesStorageReader;
     _distributedLockManager = distributedLockManager;
     _maxBinarySize          = uploadFileOptions.MaxBinarySize;
 }
コード例 #15
0
 public ObjectsStorageReader(
     VStoreContext context,
     CdnOptions cdnOptions,
     ITemplatesStorageReader templatesStorageReader,
     DistributedLockManager distributedLockManager)
 {
     _context                = context;
     _cdnOptions             = cdnOptions;
     _templatesStorageReader = templatesStorageReader;
     _distributedLockManager = distributedLockManager;
 }
コード例 #16
0
        public static OtherThreadLockHelper TryLock(object requester, DistributedLockManager lockManager, string multiprocessLockName, int timeout)
        {
            var helper = new OtherThreadLockHelper(requester, lockManager, multiprocessLockName, timeout);

            if (helper.GetMultiprocessLock())
            {
                return(helper);
            }

            helper.Dispose();
            return(null);
        }
コード例 #17
0
 public TemplatesManagementService(
     UploadFileOptions uploadFileOptions,
     CephOptions cephOptions,
     IS3Client s3Client,
     ITemplatesStorageReader templatesStorageReader,
     DistributedLockManager distributedLockManager)
 {
     _s3Client = s3Client;
     _templatesStorageReader = templatesStorageReader;
     _distributedLockManager = distributedLockManager;
     _bucketName             = cephOptions.TemplatesBucketName;
     _maxBinarySize          = uploadFileOptions.MaxBinarySize;
 }
コード例 #18
0
 public ObjectsStorageReader(
     CephOptions cephOptions,
     CdnOptions cdnOptions,
     IS3Client s3Client,
     ITemplatesStorageReader templatesStorageReader,
     DistributedLockManager distributedLockManager)
 {
     _cdnOptions             = cdnOptions;
     _s3Client               = s3Client;
     _templatesStorageReader = templatesStorageReader;
     _distributedLockManager = distributedLockManager;
     _bucketName             = cephOptions.ObjectsBucketName;
     _degreeOfParallelism    = cephOptions.DegreeOfParallelism;
 }
コード例 #19
0
 public ObjectsStorageReader(
     CephOptions cephOptions,
     VStoreOptions vStoreOptions,
     IS3Client s3Client,
     TemplatesStorageReader templatesStorageReader,
     DistributedLockManager distributedLockManager)
 {
     _s3Client = s3Client;
     _templatesStorageReader = templatesStorageReader;
     _distributedLockManager = distributedLockManager;
     _bucketName             = cephOptions.ObjectsBucketName;
     _degreeOfParallelism    = cephOptions.DegreeOfParallelism;
     _fileStorageEndpoint    = vStoreOptions.FileStorageEndpoint;
 }
コード例 #20
0
        public void Can_Not_Acquire_Same_Lock_On_Another_Thread()
        {
            var lockManager = new DistributedLockManager(GetLockProvider(DefaultLockDatabase));

            using (var outerLock = lockManager.Lock(this, MultiprocessLockName, 0))
            {
                Assert.IsNotNull(outerLock, "Unable to acquire outer lock the repository");

                using (var otherLock = OtherThreadLockHelper.TryLock(this, lockManager, MultiprocessLockName, 0))
                {
                    Assert.IsNull(otherLock, "Another thread was allowed to get the lock");
                }
            }
        }
コード例 #21
0
        public void Can_Acquire_Lock_Many_Times()
        {
            var lockManager = new DistributedLockManager(GetLockProvider(DefaultLockDatabase));

            var lockIterations = 1000;

            for (var curIteration = 0; curIteration < lockIterations; curIteration++)
            {
                using (var outerLock = lockManager.Lock(this, MultiprocessLockName, 0))
                {
                    Assert.IsNotNull(outerLock, "Unable to acquire lock on iteration {0:N0}", curIteration);
                }
            }
        }
コード例 #22
0
        public void Can_Acquire_Different_Lock_In_Same_Scope()
        {
            var lockManager = new DistributedLockManager(GetLockProvider(DefaultLockDatabase));

            // Now test other scenarios while another thread holds the lock.
            using (var otherLock = OtherThreadLockHelper.TryLock(this, lockManager, MultiprocessLockName + "_alternate", 0))
            {
                Assert.IsNotNull(otherLock, "Unable to establish first lock in scope.");

                using (var testLock = lockManager.Lock(this, MultiprocessLockName, 0))
                {
                    Assert.IsNotNull(testLock, "Unable to establish second lock in scope.");
                }
            }
        }
        public void Can_Acquire_Lock()
        {
            var lockScopePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var lockManager   = new DistributedLockManager(new FileLockProvider(lockScopePath));

            try
            {
                using (var outerLock = lockManager.Lock(this, MultiprocessLockName, 0))
                {
                    Assert.IsNotNull(outerLock, "Unable to acquire the lock");
                }
            }
            finally
            {
                Directory.Delete(lockScopePath);
            }
        }
コード例 #24
0
        public void Can_Not_Acquire_Same_Lock_In_Same_Scope()
        {
            var lockManager = new DistributedLockManager(GetLockProvider(DefaultLockDatabase));

            // Now test other scenarios while another thread holds the lock.
            using (var testLock = OtherThreadLockHelper.TryLock(this, lockManager, MultiprocessLockName, 0))
            {
                Assert.IsNotNull(testLock, "Unable to lock the repository");

                //now that I have the test lock, it should fail if I try to get it again.
                Assert.Catch <LockTimeoutException>(() =>
                {
                    using (var failedLock = lockManager.Lock(this, MultiprocessLockName, 0))
                    {
                        Assert.IsNull(failedLock, "Duplicate lock was allowed.");
                    }
                });
            }
        }
        public void Can_Acquire_Lock_With_Unsafe_Name()
        {
            var lockScopePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var lockManager   = new DistributedLockManager(new FileLockProvider(lockScopePath));

            try
            {
                var unsafeLockName = "\"M<>\"\\a/ry/ h**ad:>> a\\/:*?\"<>| li*tt|le|| la\"mb.?";

                using (var outerLock = lockManager.Lock(this, unsafeLockName, 0))
                {
                    Assert.IsNotNull(outerLock, "Unable to acquire the lock");
                }
            }
            finally
            {
                Directory.Delete(lockScopePath);
            }
        }
        public void Can_Not_Aquire_Same_Lock_On_Another_Thread()
        {
            var lockScopePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            var lockManager   = new DistributedLockManager(new FileLockProvider(lockScopePath));

            try
            {
                using (var outerLock = lockManager.Lock(this, MultiprocessLockName, 0))
                {
                    using (var otherLock = OtherThreadLockHelper.TryLock(this, lockManager, MultiprocessLockName, 0))
                    {
                        Assert.IsNull(otherLock, "Another thread was allowed to get the lock");
                    }
                }
            }
            finally
            {
                Directory.Delete(lockScopePath);
            }
        }
コード例 #27
0
 public ObjectsManagementService(
     CephOptions cephOptions,
     KafkaOptions kafkaOptions,
     IS3Client s3Client,
     TemplatesStorageReader templatesStorageReader,
     ObjectsStorageReader objectsStorageReader,
     SessionStorageReader sessionStorageReader,
     DistributedLockManager distributedLockManager,
     EventSender eventSender,
     MetricsProvider metricsProvider)
 {
     _s3Client = s3Client;
     _templatesStorageReader   = templatesStorageReader;
     _objectsStorageReader     = objectsStorageReader;
     _sessionStorageReader     = sessionStorageReader;
     _distributedLockManager   = distributedLockManager;
     _eventSender              = eventSender;
     _bucketName               = cephOptions.ObjectsBucketName;
     _objectEventsTopic        = kafkaOptions.ObjectEventsTopic;
     _referencedBinariesMetric = metricsProvider.GetReferencedBinariesMetric();
 }
コード例 #28
0
        public ObjectPersistenceTests()
        {
            var cephOptions            = new CephOptions();
            var distributedLockManager = new DistributedLockManager(
                new InMemoryLockFactory(),
                new DistributedLockOptions {
                Expiration = TimeSpan.FromHours(1)
            });
            var sessionStorageReader = new SessionStorageReader(cephOptions, _cephS3ClientMock.Object, _memoryCache);

            _objectsManagementService = new ObjectsManagementService(
                cephOptions,
                new KafkaOptions(),
                _s3ClientMock.Object,
                _templatesStorageReaderMock.Object,
                _objectsStorageReaderMock.Object,
                sessionStorageReader,
                distributedLockManager,
                _eventSender,
                new MetricsProvider());
        }
コード例 #29
0
        public void Can_ReEnter_Lock_On_Same_Thread()
        {
            var lockManager = new DistributedLockManager(GetLockProvider(DefaultLockDatabase));

            // First test new re-entrant lock capability.
            using (var outerLock = lockManager.Lock(this, MultiprocessLockName, 0))
            {
                Assert.IsNotNull(outerLock, "Unable to outer lock the repository");

                // Now check that we can get the same lock on the same thread.
                using (var middleLock = lockManager.Lock(this, MultiprocessLockName, 0))
                {
                    Assert.IsNotNull(middleLock, "Unable to reenter the repository lock on the same thread");

                    using (var innerLock = lockManager.Lock(this, MultiprocessLockName, 0))
                    {
                        Assert.IsNotNull(innerLock, "Unable to reenter the repository lock on the same thread twice");
                    }
                }
            }
        }
コード例 #30
0
 public ObjectsManagementService(
     ILogger <ObjectsManagementService> logger,
     KafkaOptions kafkaOptions,
     VStoreContext context,
     ITemplatesStorageReader templatesStorageReader,
     IObjectsStorageReader objectsStorageReader,
     SessionStorageReader sessionStorageReader,
     DistributedLockManager distributedLockManager,
     IEventSender eventSender,
     MetricsProvider metricsProvider)
 {
     _logger  = logger;
     _context = context;
     _templatesStorageReader   = templatesStorageReader;
     _objectsStorageReader     = objectsStorageReader;
     _sessionStorageReader     = sessionStorageReader;
     _distributedLockManager   = distributedLockManager;
     _eventSender              = eventSender;
     _objectEventsTopic        = kafkaOptions.ObjectEventsTopic;
     _referencedBinariesMetric = metricsProvider.GetReferencedBinariesMetric();
 }