Beispiel #1
0
        public async Task TestLockOnDifferentBlobClientTypes(
            [Values] BlobClientType type,
            [Values] bool isAsync)
        {
            if (isAsync)
            {
                await TestAsync();
            }
            else
            {
                SyncViaAsync.Run(_ => TestAsync(), default(object));
            }

            async ValueTask TestAsync()
            {
                using var provider = new TestingAzureBlobLeaseDistributedLockProvider();
                var name   = provider.GetUniqueSafeName();
                var client = CreateClient(type, name);

                if (client is AppendBlobClient appendClient)
                {
                    Assert.That(
                        Assert.Throws <RequestFailedException>(() => appendClient.CreateIfNotExists()).ToString(),
                        Does.Contain("This feature is not currently supported by the Storage Emulator")
                        );
                    return;
                }
                if (client.GetType() == typeof(BlobBaseClient))
                {
                    // work around inability to do CreateIfNotExists for the base client
                    new BlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, name).Upload(Stream.Null);
                }

                var @lock = new AzureBlobLeaseDistributedLock(client);

                await using var handle = await @lock.TryAcquireAsync();

                Assert.IsNotNull(handle);
                await using var nestedHandle = await @lock.TryAcquireAsync();

                Assert.IsNull(nestedHandle);
            }
        }
Beispiel #2
0
        public void TestSafeNaming()
        {
            var names = new[]
            {
                string.Empty,
                new string('a', 2000),
                "a/",
                "a\\",
                string.Join("/", Enumerable.Repeat("a", 254)),
                string.Join(@"\", Enumerable.Repeat("b", 254)),
                new string('/', 254),
                new string('\\', 254)
            };

            var containerClient = new BlobContainerClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName);

            foreach (var name in names)
            {
                var @lock = new AzureBlobLeaseDistributedLock(containerClient, name);
                Assert.DoesNotThrow(() => @lock.Acquire());
            }
        }
Beispiel #3
0
        public void TestCanUseLeaseIdForBlobOperations()
        {
            using var provider = new TestingAzureBlobLeaseDistributedLockProvider();
            var       name     = provider.GetUniqueSafeName();
            var       client   = new PageBlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, name);
            const int BlobSize = 512;

            client.Create(size: BlobSize);
            var @lock = new AzureBlobLeaseDistributedLock(client);

            using var handle = @lock.Acquire();
            Assert.Throws <RequestFailedException>(() => client.UploadPages(new MemoryStream(new byte[BlobSize]), offset: 0))
            .ErrorCode.ShouldEqual(AzureErrors.LeaseIdMissing);

            Assert.DoesNotThrow(
                () => client.UploadPages(new MemoryStream(new byte[BlobSize]), offset: 0, conditions: new PageBlobRequestConditions {
                LeaseId = handle.LeaseId
            })
                );

            handle.Dispose();
            Assert.Throws <ObjectDisposedException>(() => handle.LeaseId.ToString());
        }
Beispiel #4
0
        public static int Main(string[] args)
        {
            var         type = args[0];
            var         name = args[1];
            IDisposable?handle;

            switch (type)
            {
            case nameof(SqlDistributedLock):
                handle = new SqlDistributedLock(name, SqlServerCredentials.ConnectionString).Acquire();
                break;

            case "Write" + nameof(SqlDistributedReaderWriterLock):
                handle = new SqlDistributedReaderWriterLock(name, SqlServerCredentials.ConnectionString).AcquireWriteLock();
                break;

            case nameof(SqlDistributedSemaphore) + "1AsMutex":
                handle = new SqlDistributedSemaphore(name, maxCount: 1, connectionString: SqlServerCredentials.ConnectionString).Acquire();
                break;

            case nameof(SqlDistributedSemaphore) + "5AsMutex":
                handle = new SqlDistributedSemaphore(name, maxCount: 5, connectionString: SqlServerCredentials.ConnectionString).Acquire();
                break;

            case nameof(PostgresDistributedLock):
                handle = new PostgresDistributedLock(new PostgresAdvisoryLockKey(name), PostgresCredentials.GetConnectionString(Environment.CurrentDirectory)).Acquire();
                break;

            case "Write" + nameof(PostgresDistributedReaderWriterLock):
                handle = new PostgresDistributedReaderWriterLock(new PostgresAdvisoryLockKey(name), PostgresCredentials.GetConnectionString(Environment.CurrentDirectory)).AcquireWriteLock();
                break;

            case nameof(EventWaitHandleDistributedLock):
                handle = new EventWaitHandleDistributedLock(name).Acquire();
                break;

            case nameof(WaitHandleDistributedSemaphore) + "1AsMutex":
                handle = new WaitHandleDistributedSemaphore(name, maxCount: 1).Acquire();
                break;

            case nameof(WaitHandleDistributedSemaphore) + "5AsMutex":
                handle = new WaitHandleDistributedSemaphore(name, maxCount: 5).Acquire();
                break;

            case nameof(AzureBlobLeaseDistributedLock):
                handle = new AzureBlobLeaseDistributedLock(
                    new BlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, name),
                    o => o.Duration(TimeSpan.FromSeconds(15))
                    )
                         .Acquire();
                break;

            case nameof(FileDistributedLock):
                handle = new FileDistributedLock(new FileInfo(name)).Acquire();
                break;

            case nameof(RedisDistributedLock) + "1":
                handle = AcquireRedisLock(name, serverCount: 1);
                break;

            case nameof(RedisDistributedLock) + "3":
                handle = AcquireRedisLock(name, serverCount: 3);
                break;

            case nameof(RedisDistributedLock) + "2x1":
                handle = AcquireRedisLock(name, serverCount: 2);     // we know the last will fail; don't bother (we also don't know its port)
                break;

            case nameof(RedisDistributedLock) + "1WithPrefix":
                handle = AcquireRedisLock("distributed_locks:" + name, serverCount: 1);
                break;

            case "Write" + nameof(RedisDistributedReaderWriterLock) + "1":
                handle = AcquireRedisWriteLock(name, serverCount: 1);
                break;

            case "Write" + nameof(RedisDistributedReaderWriterLock) + "3":
                handle = AcquireRedisWriteLock(name, serverCount: 3);
                break;

            case "Write" + nameof(RedisDistributedReaderWriterLock) + "2x1":
                handle = AcquireRedisWriteLock(name, serverCount: 2);     // we know the last will fail; don't bother (we also don't know its port)
                break;

            case "Write" + nameof(RedisDistributedReaderWriterLock) + "1WithPrefix":
                handle = AcquireRedisWriteLock("distributed_locks:" + name, serverCount: 1);
                break;

            case string _ when type.StartsWith(nameof(RedisDistributedSemaphore)):
            {
                var maxCount = type.EndsWith("1AsMutex") ? 1
                            : type.EndsWith("5AsMutex") ? 5
                            : throw new ArgumentException(type);
                handle = new RedisDistributedSemaphore(
                    name,
                    maxCount,
                    GetRedisDatabases(serverCount: 1).Single(),
                    // in order to see abandonment work in a reasonable timeframe, use very short expiry
                    options => options.Expiry(TimeSpan.FromSeconds(1))
                    .BusyWaitSleepTime(TimeSpan.FromSeconds(.1), TimeSpan.FromSeconds(.3))
                    ).Acquire();
                break;
            }

            default:
                Console.Error.WriteLine($"type: {type}");
                return(123);
            }

            Console.WriteLine("Acquired");
            Console.Out.Flush();

            if (Console.ReadLine() != "abandon")
            {
                handle.Dispose();
            }

            return(0);
        }
 public override string GetSafeName(string name) =>
 AzureBlobLeaseDistributedLock.GetSafeName(name, new BlobContainerClient(AzureCredentials.ConnectionString, this.Strategy.ContainerName));