A library that contains a simple cosmos based distributed mutex. The mutex allows processes to coordinate access to a shared set of resources.
Install the Cosmos.Threading package via nuget package manager console:
Install-Package Cosmos.Threading
The cosmos threading mutex requires some configuration options to be set. This can be read from a configuration section from the app configuration.
"Cosmos.Threading.Mutex": {
"DatabaseId": "mutex-database",
"ContainerName": "mutex-container"
}
Setting | Description |
---|---|
DatabaseId | This is the name of the cosmos database that the mutex support containers need to be set. |
ContainerName | The name of the container to which mutex items will be read/written |
Create a container to store the mutex instances. The application has full control over the definition of the container.
await _cosmosClient
.GetDatabase(_options.Value.DatabaseId)
.CreateContainerIfNotExistsAsync(
new ContainerProperties()
{
Id = _options.Value.ContainerName,
PartitionKeyPath = MutexInitialization.PartitionKeyPath
});
To create the support containers in the cosmos database the MutexInitialization class must be used to initialize the mutex in the container.
// Initialize the default mutex
await _mutexInitialization.InitializeAsync();
// Initialize a named mutex
await _mutexInitialization.InitializeAsync(NamedMutexName);
The AcquireAsync(string, TimeSpan) method acquires the mutex. The string argument is the name of the owner attempting to acquire the mutex. The TimeSpan argument is the upper limit of the acquisition time for the mutex. After the TimeSpan the mutex can be acquired by another owner. This timeout value is to prevent a deadlocked or terminated process from holding on to the mutex.
if (await _mutex.AcquireAsync(Environment.MachineName, TimeSpan.FromSeconds(10)))
{
// Do some work and then release
await _mutex.ReleaseAsync(Environment.MachineName);
}
The AcquireAsync(string, string TimeSpan) method acquires a named mutex. The first string argument is the name of the owner attempting to acquire the mutex. The second string argument is the name of the mutex. The TimeSpan argument is the upper limit of the acquisition time for the mutex. After the TimeSpan the mutex can be acquired by another owner. This timeout value is to prevent a deadlocked or terminated process from holding on to the mutex.
if (await _mutex.AcquireAsync(Environment.MachineName, NamedMutexName, TimeSpan.FromSeconds(10)))
{
// Do some work and then release
await _mutex.ReleaseAsync(Environment.MachineName, NamedMutexName);
}