diff --git a/README.md b/README.md index ddaca1e..657f806 100644 --- a/README.md +++ b/README.md @@ -14,15 +14,17 @@ await using (await myDistributedLock.AcquireAsync()) DistributedLock contains implementations based on various technologies; you can install implementation packages individually or just install the [DistributedLock NuGet package](https://www.nuget.org/packages/DistributedLock) [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.svg?style=flat)](https://www.nuget.org/packages/DistributedLock/), a ["meta" package](https://endjin.com/blog/2020/09/streamline-dependency-management-with-nuget-meta-packages) which includes all implementations as dependencies. *Note that each package is versioned independently according to SemVer*. -- **[DistributedLock.SqlServer](docs/DistributedLock.SqlServer.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.SqlServer.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.SqlServer/): uses Microsoft SQL Server -- **[DistributedLock.Postgres](docs/DistributedLock.Postgres.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.Postgres.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.Postgres/): uses Postgresql -- **[DistributedLock.MySql](docs/DistributedLock.MySql.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.MySql.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.MySql/): uses MySQL or MariaDB -- **[DistributedLock.Oracle](docs/DistributedLock.Oracle.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.Oracle.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.Oracle/): uses Oracle -- **[DistributedLock.Redis](docs/DistributedLock.Redis.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.Redis.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.Redis/): uses Redis -- **[DistributedLock.Azure](docs/DistributedLock.Azure.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.Azure.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.Azure/): uses Azure blobs -- **[DistributedLock.ZooKeeper](docs/DistributedLock.ZooKeeper.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.ZooKeeper.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.ZooKeeper/): uses Apache ZooKeeper -- **[DistributedLock.FileSystem](docs/DistributedLock.FileSystem.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.FileSystem.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.FileSystem/): uses lock files -- **[DistributedLock.WaitHandles](docs/DistributedLock.WaitHandles.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.WaitHandles.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.WaitHandles/): uses operating system global `WaitHandle`s (Windows only) +- **[DistributedLock.SqlServer](docs/DistributedLock.SqlServer.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.SqlServer.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.SqlServer/) [![Static Badge](https://img.shields.io/badge/API%20Documentation-RobiniaDocs-43bc00?logo=readme&logoColor=white)](https://www.robiniadocs.com/d/distributedlock/api/Medallion.Threading.SqlServer.html) +: uses Microsoft SQL Server +- **[DistributedLock.Postgres](docs/DistributedLock.Postgres.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.Postgres.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.Postgres/) [![Static Badge](https://img.shields.io/badge/API%20Documentation-RobiniaDocs-43bc00?logo=readme&logoColor=white)](https://www.robiniadocs.com/d/distributedlock/api/Medallion.Threading.Postgres.html) +: uses Postgresql +- **[DistributedLock.MySql](docs/DistributedLock.MySql.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.MySql.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.MySql/) [![Static Badge](https://img.shields.io/badge/API%20Documentation-RobiniaDocs-43bc00?logo=readme&logoColor=white)](https://www.robiniadocs.com/d/distributedlock/api/Medallion.Threading.MySql.html): uses MySQL or MariaDB +- **[DistributedLock.Oracle](docs/DistributedLock.Oracle.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.Oracle.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.Oracle/) [![Static Badge](https://img.shields.io/badge/API%20Documentation-RobiniaDocs-43bc00?logo=readme&logoColor=white)](https://www.robiniadocs.com/d/distributedlock/api/Medallion.Threading.Oracle.html): uses Oracle +- **[DistributedLock.Redis](docs/DistributedLock.Redis.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.Redis.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.Redis/) [![Static Badge](https://img.shields.io/badge/API%20Documentation-RobiniaDocs-43bc00?logo=readme&logoColor=white)](https://www.robiniadocs.com/d/distributedlock/api/Medallion.Threading.Redis.html): uses Redis +- **[DistributedLock.Azure](docs/DistributedLock.Azure.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.Azure.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.Azure/) [![Static Badge](https://img.shields.io/badge/API%20Documentation-RobiniaDocs-43bc00?logo=readme&logoColor=white)](https://www.robiniadocs.com/d/distributedlock/api/Medallion.Threading.Azure.html): uses Azure blobs +- **[DistributedLock.ZooKeeper](docs/DistributedLock.ZooKeeper.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.ZooKeeper.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.ZooKeeper/) [![Static Badge](https://img.shields.io/badge/API%20Documentation-RobiniaDocs-43bc00?logo=readme&logoColor=white)](https://www.robiniadocs.com/d/distributedlock/api/Medallion.Threading.ZooKeeper.html): uses Apache ZooKeeper +- **[DistributedLock.FileSystem](docs/DistributedLock.FileSystem.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.FileSystem.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.FileSystem/) [![Static Badge](https://img.shields.io/badge/API%20Documentation-RobiniaDocs-43bc00?logo=readme&logoColor=white)](https://www.robiniadocs.com/d/distributedlock/api/Medallion.Threading.FileSystem.html): uses lock files +- **[DistributedLock.WaitHandles](docs/DistributedLock.WaitHandles.md)** [![NuGet Status](http://img.shields.io/nuget/v/DistributedLock.WaitHandles.svg?style=flat)](https://www.nuget.org/packages/DistributedLock.WaitHandles/) [![Static Badge](https://img.shields.io/badge/API%20Documentation-RobiniaDocs-43bc00?logo=readme&logoColor=white)](https://www.robiniadocs.com/d/distributedlock/api/Medallion.Threading.WaitHandles.html): uses operating system global `WaitHandle`s (Windows only) **Click on the name** of any of the above packages to see the documentation specific to that implementation, or read on for general documentation that applies to all implementations. @@ -136,12 +138,23 @@ public class SomeService Contributions are welcome! If you are interested in contributing towards a new or existing issue, please let me know via comments on the issue so that I can help you get started and avoid wasted effort on your part. +Setup steps for working with the repository locally are documented [here](docs/Developing%20DistributedLock.md). + ## Release notes +- 2.4 + - Add support for transaction-scoped locking in Postgres using `pg_advisory_xact_lock` which is helpful when using PgBouncer ([#168](https://github.com/madelson/DistributedLock/issues/168), DistributedLock.Postgres 1.1.0) + - Improve support for newer versions of StackExchange.Redis, especially when using the default backlog policy ([#162](https://github.com/madelson/DistributedLock/issues/162), DistributedLock.Redis 1.0.3). Thanks @Bartleby2718 for helping with this! + - Reduce occurrence of `UnobservedTaskException`s thrown by the library ([#192](https://github.com/madelson/DistributedLock/issues/192), DistributedLock.Core 1.0.6) + - Update dependencies to modern versions without known issues/vulnerabilities ([#111](https://github.com/madelson/DistributedLock/issues/111)/[#177](https://github.com/madelson/DistributedLock/issues/177)/[#184](https://github.com/madelson/DistributedLock/issues/184)/[#185](https://github.com/madelson/DistributedLock/issues/185), all packages). Thanks @Bartleby2718 for helping with this! + - Improve directory creation concurrency handling for `FileDistributedLock` on Linux/.NET 8 ([#195](), DistributedLock.FileSystem 1.0.2) + - Allow using transaction-scoped locks in SQL Server without explicitly disabling multiplexing ([#189](https://github.com/madelson/DistributedLock/issues/189), DistributedLock.SqlServer 1.0.4) + - New API documentation on [dndocs](https://dndocs.com/). Thanks @NeuroXiq! + - New documentation for contributors to get the project running locally (see [Contributing](#contributing)) - 2.3.4 - Support Npgsql 8.0's [ExecuteScalar breaking change](https://github.com/npgsql/npgsql/issues/5143) ([#174](https://github.com/madelson/DistributedLock/issues/174), DistributedLock.Postgres 1.0.5). Thanks [@Kaffeetasse](https://github.com/Kaffeetasse) for diagnosing and fixing! - 2.3.3 - Update Microsoft.Data.SqlClient due to vulnerabilities ([#149](https://github.com/madelson/DistributedLock/issues/149), DistributedLock.SqlServer 1.0.3) - - Update versions of Oracle.ManagedDataAccess and Oracle.ManagedDataAccess.Core due to vulnerabilities (DistributedLock.Oracle 1.0.2) + - Update versions of Oracle.ManagedDataAccess and Oracle.ManagedDataAccess.Core due to vulnerabilities (DistributedLock.Oracle 1.0.2) - 2.3.2 - Work around underlying Postgres race condition when waiting on advisory locks with a short non-zero timeout ([#147](https://github.com/madelson/DistributedLock/issues/147), DistributedLock.Postgres 1.0.4). Thanks [@Tzachi009](https://github.com/Tzachi009) for reporting and isolating the issue! - 2.3.1 diff --git a/appveyor.yml b/appveyor.yml index 29408d7..d4cd381 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,14 +1,15 @@ version: 1.0.{build} -image: +image: + # Ubuntu2204 needed for .NET 8 for now (see https://www.appveyor.com/docs/linux-images-software/) + - Ubuntu2204 - Visual Studio 2022 - - Ubuntu build_script: - dotnet build src/DistributedLock.sln -c Release test_script: - - dotnet test src/DistributedLock.sln -c Release -f netcoreapp3.1 --no-build --filter TestCategory=CI + - dotnet test src/DistributedLock.sln -c Release -f net8.0 --no-build --filter TestCategory=CI for: - diff --git a/docs/Developing DistributedLock.md b/docs/Developing DistributedLock.md new file mode 100644 index 0000000..380b848 --- /dev/null +++ b/docs/Developing DistributedLock.md @@ -0,0 +1,80 @@ +# Developing DistributedLock + +## Installing back-ends for testing + +DistributedLock has a variety of back-ends; to be able to develop and run tests against all of them you'll need to install a good amount of software. + +### Azure + +For the Azure back-end, [Azurite](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite) is used for local development. See [here](https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio%2Cblob-storage#install-azurite) for how to install. + +### MySQL + +The MySQL driver covers both MySQL and MariaDB; so we'll need to install both. + +#### MariaDB + +The MariaDB installer can be downloaded [here](https://mariadb.org/download/?t=mariadb&p=mariadb&os=windows&cpu=x86_64&pkg=msi&m=acorn). + +After downloading, you'll need to enable the performance_schema which is used by DistributedLock's tests. You can do this by adding the following to your my.ini/my.cnf file (C:\Program Files\MariaDB {version}\data\my.ini on windows): + +```ini +# activates the performance_schema tables which are needed by DistributedLock tests +performance_schema=ON +``` + +After doing this, restart MariaDB (on Windows, do this in the Services app). + +Next, create the `distributed_lock` database and a user for the tests to run as: +```sql +CREATE DATABASE distributed_lock; +CREATE USER 'DistributedLock'@'localhost' IDENTIFIED BY ''; +GRANT ALL PRIVILEGES ON distributed_lock.* TO 'DistributedLock'@'localhost'; +GRANT SELECT ON performance_schema.* TO 'DistributedLock'@'localhost'; +``` + +Finally, add your username (DistributedLock) and password to `DistributedLock.Tests/credentials/mariadb.txt`, with the username on line 1 and the password on line 2. + +#### MySQL + +You can install MySQL from [here](https://dev.mysql.com/downloads/mysql/). Run on port 3307 to avoid conflicting with MariaDB. + +Add your username and password to `DistributedLock.Tests/credentials/mysql.txt`, with the username on line 1 and the password on line 2. + +### Oracle + +You can install Oracle from [here](https://www.oracle.com/database/technologies/oracle-database-software-downloads.html#db_free). It claims not to support Windows 11 Home, but it seems to install and work fine. + +Add your username (e.g. SYSTEM) and password to `DistributedLock.Tests/credentials/oracle.txt`, with the username on line 1 and the password on line 2. + +If the Oracle tests fail with `ORA-12541: TNS:no listener`, you may have to start the OracleOraDB21Home1TNSListener service in services.svc and/or restart the OracleServiceXE. After starting these it can take a few minutes for the DB to come online. + +### Postgres + +You can install Postgres from [here](https://www.enterprisedb.com/downloads/postgres-postgresql-downloads). + +In `C:\Program Files\PostgreSQL\\data\postgresql.conf`, update `max_connections` to 200. + +Add your username (e.g. postgres) and password to `DistributedLock.Tests/credentials/postgres.txt`, with the username on line 1 and the password on line 2. + +### SQL Server + +Download SQL developer edition from [here](https://www.microsoft.com/en-us/sql-server/sql-server-downloads). + +The tests connect via integrated security. + +### Redis + +Install Redis locally. On Windows, install it via WSL as described [here](https://developer.redis.com/create/windows/). + +You do not need it running as a service: the tests will start and stop instances automatically. + +### ZooKeeper + +Download a ZooKeeper installation by going to [https://zookeeper.apache.org/](https://zookeeper.apache.org/)->Documentation->Release ...->Getting Started->Download->stable. + +Extract the zip archive, and within it copy `zoo_sample.cfg` to `zoo.cfg`. + +Add the full path of the extracted directory (the one containing README.md, bin, conf, etc) to `DistributedLock.Tests/credentials/zookeeper.txt` as a single line. + +Also, install Java Development Kit (JDK) because ZooKeeper runs on Java. diff --git a/docs/DistributedLock.Postgres.md b/docs/DistributedLock.Postgres.md index fc433ab..da92dea 100644 --- a/docs/DistributedLock.Postgres.md +++ b/docs/DistributedLock.Postgres.md @@ -35,6 +35,7 @@ In addition to specifying the `key`, Postgres-based locks allow you to specify e In addition to specifying the `key`, several tuning options are available for `connectionString`-based locks: - `KeepaliveCadence` allows you to have the implementation periodically issue a cheap query on a connection holding a lock. This helps in configurations which are set up to aggressively kill idle connections. Defaults to OFF (`Timeout.InfiniteTimeSpan`). +- `UseTransaction` scopes the lock to an internally-managed transaction under the hood (otherwise it is connection-scoped). Defaults to FALSE because this mode is not compatible with multiplexing and thus consumes more connections. - `UseMultiplexing` allows the implementation to re-use connections under the hood to hold multiple locks under certain scenarios, leading to lower resource consumption. This behavior defaults to ON; you should not disable it unless you suspect that it is causing issues for you (please file an issue here if so!). diff --git a/docs/DistributedLock.SqlServer.md b/docs/DistributedLock.SqlServer.md index adeb2c9..d324528 100644 --- a/docs/DistributedLock.SqlServer.md +++ b/docs/DistributedLock.SqlServer.md @@ -28,5 +28,5 @@ SQL-based locks can be constructed with a connection string, an `IDbConnection`, When connecting using a `connectionString`, several other tuning options can also be specified. - `KeepaliveCadence` configures the frequency at which an innocuous query will be issued on the connection while the lock is being held. The purpose of automatic keepalive is to prevent SQL Azure's aggressive connection governor from killing "idle" lock-holding connections. Defaults to 10 minutes. -- `UseTransaction` scopes the lock to an internally-managed transaction under the hood (otherwise it is connection-scoped). Defaults to FALSE because this mode can lead to long-running transactions which can be disruptive on databases using the full recovery model. -- `UseMultiplexing` allows the implementation to re-use connections under the hood to hold multiple locks under certain scenarios, leading to lower resource consumption. This behavior defaults to ON; you should not disable it unless you suspect that it is causing issues for you (please file an issue here if so!). +- `UseTransaction` scopes the lock to an internally-managed transaction under the hood (otherwise it is connection-scoped). Defaults to FALSE because this mode is not compatible with multiplexing and thus consumes more connections. It can also lead to long-running transactions which can be disruptive on databases using the full recovery model. +- `UseMultiplexing` allows the implementation to re-use connections under the hood to hold multiple locks under certain scenarios, leading to lower resource consumption. This behavior defaults to ON except in the case where `UseTransaction` is set to TRUE since the two are not compatible. You should only manually disable `UseMultiplexing` for troubleshooting purposes if you suspect it is causing issues. diff --git a/src/Directory.Build.props b/src/Directory.Build.props new file mode 100644 index 0000000..7f4a6cc --- /dev/null +++ b/src/Directory.Build.props @@ -0,0 +1,13 @@ + + + true + + true + package.readme.md + + + + + + + \ No newline at end of file diff --git a/src/CopyPackageToPublishDirectory.targets b/src/Directory.Build.targets similarity index 100% rename from src/CopyPackageToPublishDirectory.targets rename to src/Directory.Build.targets diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props new file mode 100644 index 0000000..7afc027 --- /dev/null +++ b/src/Directory.Packages.props @@ -0,0 +1,29 @@ + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider.cs b/src/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider.cs index 9a40556..417dba3 100644 --- a/src/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider.cs +++ b/src/DistributedLock.Azure/AzureBlobLeaseDistributedSynchronizationProvider.cs @@ -22,7 +22,7 @@ public AzureBlobLeaseDistributedSynchronizationProvider(BlobContainerClient blob /// /// Constructs an with the given . /// - public AzureBlobLeaseDistributedLock CreateLock(string name) => new AzureBlobLeaseDistributedLock(this._blobContainerClient, name, this._options); + public AzureBlobLeaseDistributedLock CreateLock(string name) => new(this._blobContainerClient, name, this._options); IDistributedLock IDistributedLockProvider.CreateLock(string name) => this.CreateLock(name); } diff --git a/src/DistributedLock.Azure/BlobClientWrapper.cs b/src/DistributedLock.Azure/BlobClientWrapper.cs index ffca59d..6d9839a 100644 --- a/src/DistributedLock.Azure/BlobClientWrapper.cs +++ b/src/DistributedLock.Azure/BlobClientWrapper.cs @@ -19,7 +19,7 @@ public BlobClientWrapper(BlobBaseClient blobClient) public string Name => this._blobClient.Name; - public BlobLeaseClientWrapper GetBlobLeaseClient() => new BlobLeaseClientWrapper(this._blobClient.GetBlobLeaseClient()); + public BlobLeaseClientWrapper GetBlobLeaseClient() => new(this._blobClient.GetBlobLeaseClient()); public async ValueTask> GetMetadataAsync(string leaseId, CancellationToken cancellationToken) { diff --git a/src/DistributedLock.Azure/DistributedLock.Azure.csproj b/src/DistributedLock.Azure/DistributedLock.Azure.csproj index 4140150..cf1c356 100644 --- a/src/DistributedLock.Azure/DistributedLock.Azure.csproj +++ b/src/DistributedLock.Azure/DistributedLock.Azure.csproj @@ -1,7 +1,7 @@ - netstandard2.0;netstandard2.1;net461 + netstandard2.0;netstandard2.1;net462 Medallion.Threading.Azure True 4 @@ -11,7 +11,7 @@ - 1.0.0 + 1.0.1 1.0.0.0 Michael Adelson Provides a distributed locking implementation based on Azure blob leases @@ -42,15 +42,14 @@ - - - + + + - \ No newline at end of file diff --git a/src/DistributedLock.Azure/packages.lock.json b/src/DistributedLock.Azure/packages.lock.json new file mode 100644 index 0000000..f491b7e --- /dev/null +++ b/src/DistributedLock.Azure/packages.lock.json @@ -0,0 +1,552 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "Azure.Storage.Blobs": { + "type": "Direct", + "requested": "[12.19.1, )", + "resolved": "12.19.1", + "contentHash": "x43hWFJ4sPQ23TD4piCwT+KlQpZT8pNDAzqj6yUCqh+WJ2qcQa17e1gh6ZOeT2QNFQTTDSuR56fm2bIV7i11/w==", + "dependencies": { + "Azure.Storage.Common": "12.18.1", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.36.0", + "contentHash": "vwqFZdHS4dzPlI7FFRkPx9ctA+aGGeRev3gnzG8lntWvKMmBhAmulABi1O9CEvS3/jzYt7yA+0pqVdxkpAd7dQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Net.Http": "4.3.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.18.1", + "contentHash": "ohCslqP9yDKIn+DVjBEOBuieB1QwsUCz+BwHYNaJ3lcIsTSiI4Evnq81HcKe8CqM8qvdModbipVQKpnxpbdWqA==", + "dependencies": { + "Azure.Core": "1.36.0", + "System.IO.Hashing": "6.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "KiLYDu2k2J82Q9BJpWiuQqCkFjRBWVq4jDzKKWawVi9KWzyD0XG3cmfX0vqTQlL14Wi9EufJrbL0+KCLTbqWiQ==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Rfm2jYCaUeGysFEZjDe7j1R4x6Z6BzumS/vUT5a1AA/AWJuGX71PoGB0RmpyX3VmrGqVnAwtfMn39OHR8Y/5+g==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Net.Http": { + "type": "Transitive", + "resolved": "4.3.4", + "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", + "dependencies": { + "System.Security.Cryptography.X509Certificates": "4.3.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Runtime.InteropServices.RuntimeInformation": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==" + }, + "System.Security.Cryptography.Algorithms": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==", + "dependencies": { + "System.Security.Cryptography.Primitives": "4.3.0" + } + }, + "System.Security.Cryptography.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==" + }, + "System.Security.Cryptography.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==" + }, + "System.Security.Cryptography.X509Certificates": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==", + "dependencies": { + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0" + } + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "TcMd95wcrubm9nHvJEQs70rC0H/8omiSGGpU4FQ/ZA1URIqD4pjmFJh2Mfv1yH1eHgJDWTi2hMDXwTET+zOOyg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.1", + "System.Text.Encodings.Web": "4.7.1", + "System.Threading.Tasks.Extensions": "4.5.4", + "System.ValueTuple": "4.5.0" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.ValueTuple": { + "type": "CentralTransitive", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + } + }, + ".NETStandard,Version=v2.0": { + "Azure.Storage.Blobs": { + "type": "Direct", + "requested": "[12.19.1, )", + "resolved": "12.19.1", + "contentHash": "x43hWFJ4sPQ23TD4piCwT+KlQpZT8pNDAzqj6yUCqh+WJ2qcQa17e1gh6ZOeT2QNFQTTDSuR56fm2bIV7i11/w==", + "dependencies": { + "Azure.Storage.Common": "12.18.1", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.36.0", + "contentHash": "vwqFZdHS4dzPlI7FFRkPx9ctA+aGGeRev3gnzG8lntWvKMmBhAmulABi1O9CEvS3/jzYt7yA+0pqVdxkpAd7dQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.18.1", + "contentHash": "ohCslqP9yDKIn+DVjBEOBuieB1QwsUCz+BwHYNaJ3lcIsTSiI4Evnq81HcKe8CqM8qvdModbipVQKpnxpbdWqA==", + "dependencies": { + "Azure.Core": "1.36.0", + "System.IO.Hashing": "6.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "KiLYDu2k2J82Q9BJpWiuQqCkFjRBWVq4jDzKKWawVi9KWzyD0XG3cmfX0vqTQlL14Wi9EufJrbL0+KCLTbqWiQ==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Rfm2jYCaUeGysFEZjDe7j1R4x6Z6BzumS/vUT5a1AA/AWJuGX71PoGB0RmpyX3VmrGqVnAwtfMn39OHR8Y/5+g==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "TcMd95wcrubm9nHvJEQs70rC0H/8omiSGGpU4FQ/ZA1URIqD4pjmFJh2Mfv1yH1eHgJDWTi2hMDXwTET+zOOyg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.1", + "System.Text.Encodings.Web": "4.7.1", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + } + }, + ".NETStandard,Version=v2.1": { + "Azure.Storage.Blobs": { + "type": "Direct", + "requested": "[12.19.1, )", + "resolved": "12.19.1", + "contentHash": "x43hWFJ4sPQ23TD4piCwT+KlQpZT8pNDAzqj6yUCqh+WJ2qcQa17e1gh6ZOeT2QNFQTTDSuR56fm2bIV7i11/w==", + "dependencies": { + "Azure.Storage.Common": "12.18.1", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.36.0", + "contentHash": "vwqFZdHS4dzPlI7FFRkPx9ctA+aGGeRev3gnzG8lntWvKMmBhAmulABi1O9CEvS3/jzYt7yA+0pqVdxkpAd7dQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.18.1", + "contentHash": "ohCslqP9yDKIn+DVjBEOBuieB1QwsUCz+BwHYNaJ3lcIsTSiI4Evnq81HcKe8CqM8qvdModbipVQKpnxpbdWqA==", + "dependencies": { + "Azure.Core": "1.36.0", + "System.IO.Hashing": "6.0.0" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "yuvf07qFWFqtK3P/MRkEKLhn5r2UbSpVueRziSqj0yJQIKFwG1pq9mOayK3zE5qZCTs0CbrwL9M6R8VwqyGy2w==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "KiLYDu2k2J82Q9BJpWiuQqCkFjRBWVq4jDzKKWawVi9KWzyD0XG3cmfX0vqTQlL14Wi9EufJrbL0+KCLTbqWiQ==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Rfm2jYCaUeGysFEZjDe7j1R4x6Z6BzumS/vUT5a1AA/AWJuGX71PoGB0RmpyX3VmrGqVnAwtfMn39OHR8Y/5+g==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "TcMd95wcrubm9nHvJEQs70rC0H/8omiSGGpU4FQ/ZA1URIqD4pjmFJh2Mfv1yH1eHgJDWTi2hMDXwTET+zOOyg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.1", + "System.Text.Encodings.Web": "4.7.1", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.Core/DeadlockException.cs b/src/DistributedLock.Core/DeadlockException.cs index f9fb233..917b0bf 100644 --- a/src/DistributedLock.Core/DeadlockException.cs +++ b/src/DistributedLock.Core/DeadlockException.cs @@ -24,5 +24,8 @@ public DeadlockException(string message) : base(message) { } /// public DeadlockException(string message, Exception innerException) : base(message, innerException) { } +#if NET8_0_OR_GREATER + [Obsolete] // calls obsolete constructor +#endif private DeadlockException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context) : base(info, context) { } } diff --git a/src/DistributedLock.Core/DistributedLock.Core.csproj b/src/DistributedLock.Core/DistributedLock.Core.csproj index df5c7c0..3f559bd 100644 --- a/src/DistributedLock.Core/DistributedLock.Core.csproj +++ b/src/DistributedLock.Core/DistributedLock.Core.csproj @@ -1,7 +1,7 @@ - netstandard2.0;netstandard2.1;net461 + net8.0;netstandard2.0;netstandard2.1;net462 Medallion.Threading True 4 @@ -11,7 +11,7 @@ - 1.0.5 + 1.0.6 1.0.0.0 Michael Adelson Core interfaces and utilities that support the DistributedLock.* family of packages @@ -44,22 +44,20 @@ TRACE;DEBUG - - + + - - + + - - + + - - \ No newline at end of file diff --git a/src/DistributedLock.Core/Internal/AsyncLock.cs b/src/DistributedLock.Core/Internal/AsyncLock.cs index 78bcebe..8fceef0 100644 --- a/src/DistributedLock.Core/Internal/AsyncLock.cs +++ b/src/DistributedLock.Core/Internal/AsyncLock.cs @@ -14,7 +14,7 @@ private AsyncLock(SemaphoreSlim semaphore) this._semaphore = semaphore; } - public static AsyncLock Create() => new AsyncLock(new SemaphoreSlim(initialCount: 1, maxCount: 1)); + public static AsyncLock Create() => new(new SemaphoreSlim(initialCount: 1, maxCount: 1)); public async ValueTask AcquireAsync(CancellationToken cancellationToken) { diff --git a/src/DistributedLock.Core/Internal/Data/ConnectionMonitor.cs b/src/DistributedLock.Core/Internal/Data/ConnectionMonitor.cs index 9615c50..6e87b68 100644 --- a/src/DistributedLock.Core/Internal/Data/ConnectionMonitor.cs +++ b/src/DistributedLock.Core/Internal/Data/ConnectionMonitor.cs @@ -310,7 +310,7 @@ private bool StartMonitorWorkerIfNeededNoLock() // one is spinning down. If we change states in rapid succession we could end up with multiple tasks queued up // but this shouldn't matter since when the active one ultimately stops all the others will follow in rapid succession this._monitoringWorkerTask = this._monitoringWorkerTask - .ContinueWith((_, state) => ((ConnectionMonitor)state).MonitorWorkerLoop(), state: this) + .ContinueWith((_, state) => ((ConnectionMonitor)state!).MonitorWorkerLoop(), state: this) .Unwrap(); this._state = State.Active; return true; diff --git a/src/DistributedLock.Core/Internal/Data/DatabaseCommand.cs b/src/DistributedLock.Core/Internal/Data/DatabaseCommand.cs index 624ffb0..54ff5b8 100644 --- a/src/DistributedLock.Core/Internal/Data/DatabaseCommand.cs +++ b/src/DistributedLock.Core/Internal/Data/DatabaseCommand.cs @@ -63,7 +63,7 @@ public ValueTask ExecuteNonQueryAsync(CancellationToken cancellationToken, internal ValueTask ExecuteNonQueryAsync(CancellationToken cancellationToken, bool disallowAsyncCancellation, bool isConnectionMonitoringQuery) => this.ExecuteAsync((c, t) => c.ExecuteNonQueryAsync(t), c => c.ExecuteNonQuery(), cancellationToken, disallowAsyncCancellation, isConnectionMonitoringQuery); - public ValueTask ExecuteScalarAsync(CancellationToken cancellationToken, bool disallowAsyncCancellation = false) => + public ValueTask ExecuteScalarAsync(CancellationToken cancellationToken, bool disallowAsyncCancellation = false) => this.ExecuteAsync((c, t) => c.ExecuteScalarAsync(t), c => c.ExecuteScalar(), cancellationToken, disallowAsyncCancellation, isConnectionMonitoringQuery: false); private async ValueTask ExecuteAsync( @@ -113,7 +113,7 @@ private async ValueTask ExecuteAsync( // registrations fire synchronously if the token is already canceled using var registration = cancellationToken.Register(state => Task.Run(async () => { - var commandBox = (StrongBox)state; + var commandBox = (StrongBox)state!; IDbCommand? command; while ((command = Volatile.Read(ref commandBox.Value)) != null) { @@ -153,9 +153,7 @@ private async ValueTask InternalExecuteAndPropagateCancellationAsync. /// public DedicatedConnectionOrTransactionDbDistributedLock(string name, Func externalConnectionFactory) + // MA: useTransaction:true here is a bit weird. However, in practice this value does not impact the external connection + // flow so it doesn't matter what the value is. : this(name, externalConnectionFactory, useTransaction: true, keepaliveCadence: Timeout.InfiniteTimeSpan) { } @@ -52,7 +54,7 @@ public DedicatedConnectionOrTransactionDbDistributedLock( DatabaseConnection connection; if (contextHandle != null) { - connection = GetContextHandleConnection(contextHandle); + connection = this.GetContextHandleConnection(contextHandle); } else { diff --git a/src/DistributedLock.Core/Internal/Data/MultiplexedConnectionLock.cs b/src/DistributedLock.Core/Internal/Data/MultiplexedConnectionLock.cs index d25db84..5187017 100644 --- a/src/DistributedLock.Core/Internal/Data/MultiplexedConnectionLock.cs +++ b/src/DistributedLock.Core/Internal/Data/MultiplexedConnectionLock.cs @@ -11,7 +11,7 @@ internal sealed class MultiplexedConnectionLock : IAsyncDisposable /// Protects access to and /// private readonly AsyncLock _mutex = AsyncLock.Create(); - private readonly Dictionary _heldLocksToKeepaliveCadences = new Dictionary(); + private readonly Dictionary _heldLocksToKeepaliveCadences = []; private readonly DatabaseConnection _connection; /// /// Tracks whether we've successfully opened the connection. We track this explicity instead of just looking at @@ -106,7 +106,7 @@ public async ValueTask GetIsInUseAsync() private Result GetAlreadyBrokenResultNoLock() => // Retry on any already-broken connection to avoid "leaking" the killing or death of connections. We want there to be no observable // results (other than perf) of multiplexing vs. not. - new Result(MultiplexedConnectionLockRetry.Retry, canSafelyDispose: this._heldLocksToKeepaliveCadences.Count == 0); + new(MultiplexedConnectionLockRetry.Retry, canSafelyDispose: this._heldLocksToKeepaliveCadences.Count == 0); private Result GetFailureResultNoLock(bool isAlreadyHeld, bool opportunistic, TimeoutValue timeout) { diff --git a/src/DistributedLock.Core/Internal/Data/MultiplexedConnectionLockPool.cs b/src/DistributedLock.Core/Internal/Data/MultiplexedConnectionLockPool.cs index e4b94f8..fc96865 100644 --- a/src/DistributedLock.Core/Internal/Data/MultiplexedConnectionLockPool.cs +++ b/src/DistributedLock.Core/Internal/Data/MultiplexedConnectionLockPool.cs @@ -12,8 +12,8 @@ sealed class MultiplexedConnectionLockPool { private readonly AsyncLock _lock = AsyncLock.Create(); - private readonly Dictionary> _poolsByConnectionString = - new Dictionary>(); + private readonly Dictionary> _poolsByConnectionString = []; + /// /// The number of times we've called /// since we last called diff --git a/src/DistributedLock.Core/Internal/Helpers.cs b/src/DistributedLock.Core/Internal/Helpers.cs index 67d6a72..d77cd1d 100644 --- a/src/DistributedLock.Core/Internal/Helpers.cs +++ b/src/DistributedLock.Core/Internal/Helpers.cs @@ -30,9 +30,9 @@ public readonly struct TaskConversion { } internal static async ValueTask ConvertToVoid(this ValueTask task) => await task.ConfigureAwait(false); - public static ValueTask AsValueTask(this Task task) => new ValueTask(task); - public static ValueTask AsValueTask(this Task task) => new ValueTask(task); - public static ValueTask AsValueTask(this T value) => new ValueTask(value); + public static ValueTask AsValueTask(this Task task) => new(task); + public static ValueTask AsValueTask(this Task task) => new(task); + public static ValueTask AsValueTask(this T value) => new(value); public static Task SafeCreateTask(Func> taskFactory, TState state) => InternalSafeCreateTask, TResult>(taskFactory, state); @@ -59,7 +59,7 @@ public static ObjectDisposedException ObjectDisposed(this T _) where T : IAsy throw new ObjectDisposedException(typeof(T).ToString()); public static NonThrowingAwaitable TryAwait(this TTask task) where TTask : Task => - new NonThrowingAwaitable(task); + new(task); /// /// Throwing exceptions is slow and our workflow has us canceling tasks in the common case. Using this special awaitable @@ -74,7 +74,11 @@ public static NonThrowingAwaitable TryAwait(this TTask task) where public NonThrowingAwaitable(TTask task) { this._task = task; +#if NET8_0_OR_GREATER + this._taskAwaiter = task.ConfigureAwait(ConfigureAwaitOptions.SuppressThrowing).GetAwaiter(); +#else this._taskAwaiter = task.ConfigureAwait(false).GetAwaiter(); +#endif } public NonThrowingAwaitable GetAwaiter() => this; @@ -83,9 +87,16 @@ public NonThrowingAwaitable(TTask task) public TTask GetResult() { - // does NOT call _taskAwaiter.GetResult() since that could throw! - Invariant.Require(this._task.IsCompleted); + +#if NET8_0_OR_GREATER + this._taskAwaiter.GetResult(); +#else + // Does NOT call _taskAwaiter.GetResult() since that could throw! + // We do, however, access the Exception property to avoid hitting UnobservedTaskException. + if (this._task.IsFaulted) { _ = this._task.Exception; } +#endif + return this._task; } diff --git a/src/DistributedLock.Core/Internal/LeaseMonitor.cs b/src/DistributedLock.Core/Internal/LeaseMonitor.cs index f81ea8c..7154912 100644 --- a/src/DistributedLock.Core/Internal/LeaseMonitor.cs +++ b/src/DistributedLock.Core/Internal/LeaseMonitor.cs @@ -12,8 +12,8 @@ namespace Medallion.Threading.Internal; #endif sealed class LeaseMonitor : IDisposable, IAsyncDisposable { - private readonly CancellationTokenSource _disposalSource = new CancellationTokenSource(), - _handleLostSource = new CancellationTokenSource(); + private readonly CancellationTokenSource _disposalSource = new(), + _handleLostSource = new(); private readonly ILeaseHandle _leaseHandle; private readonly Task _monitoringTask; @@ -46,7 +46,7 @@ public async ValueTask DisposeAsync() { if (this._cancellationTask != null) { - _ = this._cancellationTask.ContinueWith((_, state) => ((CancellationTokenSource)state).Dispose(), state: this._handleLostSource); + _ = this._cancellationTask.ContinueWith((_, state) => ((CancellationTokenSource)state!).Dispose(), state: this._handleLostSource); } else { diff --git a/src/DistributedLock.Core/Internal/ManagedFinalizerQueue.cs b/src/DistributedLock.Core/Internal/ManagedFinalizerQueue.cs index 4247a12..55de617 100644 --- a/src/DistributedLock.Core/Internal/ManagedFinalizerQueue.cs +++ b/src/DistributedLock.Core/Internal/ManagedFinalizerQueue.cs @@ -24,9 +24,9 @@ sealed class ManagedFinalizerQueue #endif ); - public static readonly ManagedFinalizerQueue Instance = new ManagedFinalizerQueue(); + public static readonly ManagedFinalizerQueue Instance = new(); - private readonly ConcurrentDictionary _items = new ConcurrentDictionary(); + private readonly ConcurrentDictionary _items = new(); // The state of this class can be described by 3 bits: // _count: >0 or ==0 @@ -101,7 +101,7 @@ private void StartFinalizerTask() // necessarily exited yet (and may not for some time). Therefore, we queue a task to run as a // continuation so that we only have one finalizer loop at a time this._finalizerTask = this._finalizerTask.ContinueWith( - (_, @this) => ((ManagedFinalizerQueue)@this).FinalizerLoop(), + (_, @this) => ((ManagedFinalizerQueue)@this!).FinalizerLoop(), state: this, CancellationToken.None ) diff --git a/src/DistributedLock.Core/Internal/RefBox.cs b/src/DistributedLock.Core/Internal/RefBox.cs index 4fcb63d..718cee4 100644 --- a/src/DistributedLock.Core/Internal/RefBox.cs +++ b/src/DistributedLock.Core/Internal/RefBox.cs @@ -30,7 +30,7 @@ internal RefBox(T value) #endif sealed class RefBox { - public static RefBox Create(T value) where T : struct => new RefBox(value); + public static RefBox Create(T value) where T : struct => new(value); /// /// Thread-safely checks if is non-null and if so sets it to null and outputs diff --git a/src/DistributedLock.Core/Internal/TimeoutValue.cs b/src/DistributedLock.Core/Internal/TimeoutValue.cs index 671e670..ff5997c 100644 --- a/src/DistributedLock.Core/Internal/TimeoutValue.cs +++ b/src/DistributedLock.Core/Internal/TimeoutValue.cs @@ -53,7 +53,7 @@ public int CompareTo(TimeoutValue that) => public static bool operator ==(TimeoutValue a, TimeoutValue b) => a.Equals(b); public static bool operator !=(TimeoutValue a, TimeoutValue b) => !(a == b); - public static implicit operator TimeoutValue(TimeSpan? timeout) => new TimeoutValue(timeout); + public static implicit operator TimeoutValue(TimeSpan? timeout) => new(timeout); public override string ToString() => this.IsInfinite ? "∞" diff --git a/src/DistributedLock.Core/packages.lock.json b/src/DistributedLock.Core/packages.lock.json new file mode 100644 index 0000000..0584aab --- /dev/null +++ b/src/DistributedLock.Core/packages.lock.json @@ -0,0 +1,201 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "System.ValueTuple": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + } + }, + ".NETStandard,Version=v2.0": { + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + } + }, + ".NETStandard,Version=v2.1": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + } + }, + "net8.0": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NET.ILLink.Tasks": { + "type": "Direct", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "hKTrehpfVzOhAz0mreaTAZgbz0DrMEbWq4n3hAo8Ks6WdxdqQhNPvzOqn9VygKuWf1bmxPdraqzTaXriO/sn0A==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.FileSystem/DistributedLock.FileSystem.csproj b/src/DistributedLock.FileSystem/DistributedLock.FileSystem.csproj index 079cda1..5a89109 100644 --- a/src/DistributedLock.FileSystem/DistributedLock.FileSystem.csproj +++ b/src/DistributedLock.FileSystem/DistributedLock.FileSystem.csproj @@ -1,7 +1,7 @@ - net461;netstandard2.0;netstandard2.1 + net462;netstandard2.0;netstandard2.1 Medallion.Threading.FileSystem True 4 @@ -11,7 +11,7 @@ - 1.0.1 + 1.0.2 1.0.0.0 Michael Adelson Provides a distributed lock implementation based on file locks @@ -49,17 +49,16 @@ - + all - - + + - \ No newline at end of file diff --git a/src/DistributedLock.FileSystem/FileDistributedLock.cs b/src/DistributedLock.FileSystem/FileDistributedLock.cs index 0cd633a..2001570 100644 --- a/src/DistributedLock.FileSystem/FileDistributedLock.cs +++ b/src/DistributedLock.FileSystem/FileDistributedLock.cs @@ -12,7 +12,7 @@ public sealed partial class FileDistributedLock : IInternalDistributedLock - private const int MaxUnauthorizedAccessExceptionRetries = 400; + private const int MaxUnauthorizedAccessExceptionRetries = 800; // These are not configurable currently because in the future we may want to change the implementation of FileDistributedLock // to leverage native methods which may allow for actual blocking. The values here reflect the idea that we expect file locks @@ -110,7 +110,7 @@ public FileDistributedLock(DirectoryInfo lockFileDirectory, string name) // Frustratingly, this error can be thrown transiently due to concurrent creation/deletion. Initially assume // that it is transient and just retry - if (++retryCount <= MaxUnauthorizedAccessExceptionRetries) + if (CanRetryTransientFileSystemError(ref retryCount)) { continue; } @@ -142,13 +142,30 @@ private void EnsureDirectoryExists() System.IO.Directory.CreateDirectory(this.Directory); return; } - // This can indicate either a transient failure during concurrent creation/deletion or a permissions issue. - // If we encounter it, assume it is transient unless it persists. - catch (UnauthorizedAccessException) when (++retryCount <= MaxUnauthorizedAccessExceptionRetries) { } catch (Exception ex) { + // This can indicate either a transient failure during concurrent creation/deletion or a permissions issue. + // If we encounter it, assume it is transient unless it persists. + // For a long time, I just checked for UnauthorizedAccessException here. However, recent tests on Linux have + // shown that in race conditions we can see IOException as well, presumably because there is some period during + // directory creation where it presents as a file. + if (ex is UnauthorizedAccessException or IOException + && CanRetryTransientFileSystemError(ref retryCount)) + { + continue; + } + throw new InvalidOperationException($"Failed to ensure that lock file directory {this.Directory} exists", ex); } } } + + private static bool CanRetryTransientFileSystemError(ref int retryCount) + { + if (retryCount >= MaxUnauthorizedAccessExceptionRetries) { return false; } + + ++retryCount; + + return true; + } } diff --git a/src/DistributedLock.FileSystem/FileDistributedSynchronizationProvider.cs b/src/DistributedLock.FileSystem/FileDistributedSynchronizationProvider.cs index 0d3ef27..6d722a7 100644 --- a/src/DistributedLock.FileSystem/FileDistributedSynchronizationProvider.cs +++ b/src/DistributedLock.FileSystem/FileDistributedSynchronizationProvider.cs @@ -18,7 +18,7 @@ public FileDistributedSynchronizationProvider(DirectoryInfo lockFileDirectory) /// /// Constructs a with the given . /// - public FileDistributedLock CreateLock(string name) => new FileDistributedLock(this._lockFileDirectory, name); + public FileDistributedLock CreateLock(string name) => new(this._lockFileDirectory, name); IDistributedLock IDistributedLockProvider.CreateLock(string name) => this.CreateLock(name); } diff --git a/src/DistributedLock.FileSystem/packages.lock.json b/src/DistributedLock.FileSystem/packages.lock.json new file mode 100644 index 0000000..adc5221 --- /dev/null +++ b/src/DistributedLock.FileSystem/packages.lock.json @@ -0,0 +1,195 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Nullable": { + "type": "Direct", + "requested": "[1.3.1, )", + "resolved": "1.3.1", + "contentHash": "Mk4ZVDfAORTjvckQprCSehi1XgOAAlk5ez06Va/acRYEloN9t6d6zpzJRn5MEq7+RnagyFIq9r+kbWzLGd+6QA==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.ValueTuple": { + "type": "CentralTransitive", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + } + }, + ".NETStandard,Version=v2.0": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Nullable": { + "type": "Direct", + "requested": "[1.3.1, )", + "resolved": "1.3.1", + "contentHash": "Mk4ZVDfAORTjvckQprCSehi1XgOAAlk5ez06Va/acRYEloN9t6d6zpzJRn5MEq7+RnagyFIq9r+kbWzLGd+6QA==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + } + }, + ".NETStandard,Version=v2.1": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "distributedlock.core": { + "type": "Project" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.MySql/DistributedLock.MySql.csproj b/src/DistributedLock.MySql/DistributedLock.MySql.csproj index 95c4436..ba277a4 100644 --- a/src/DistributedLock.MySql/DistributedLock.MySql.csproj +++ b/src/DistributedLock.MySql/DistributedLock.MySql.csproj @@ -1,7 +1,7 @@ - netstandard2.0;netstandard2.1;net461 + netstandard2.0;netstandard2.1;net462 Medallion.Threading.MySql True 4 @@ -11,7 +11,7 @@ - 1.0.1 + 1.0.2 1.0.0.0 Michael Adelson Provides a distributed lock implementation based on MySql @@ -46,9 +46,9 @@ - - - + + + @@ -59,6 +59,5 @@ - \ No newline at end of file diff --git a/src/DistributedLock.MySql/packages.lock.json b/src/DistributedLock.MySql/packages.lock.json new file mode 100644 index 0000000..2d1d4b8 --- /dev/null +++ b/src/DistributedLock.MySql/packages.lock.json @@ -0,0 +1,334 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "MySqlConnector": { + "type": "Direct", + "requested": "[2.3.5, )", + "resolved": "2.3.5", + "contentHash": "AmEfUPkFl+Ev6jJ8Dhns3CYHBfD12RHzGYWuLt6DfG6/af6YvOMyPz74ZPPjBYQGRJkumD2Z48Kqm8s5DJuhLA==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "7.0.1", + "System.Diagnostics.DiagnosticSource": "7.0.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "7.0.1", + "contentHash": "pkeBFx0vqMW/A3aUVHh7MPu3WkBhaVlezhSZeb1c9XD0vUReYH1TLFSy5MxJgZfmz5LZzYoErMorlYZiwpOoNA==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "7.0.2", + "contentHash": "hYr3I9N9811e0Bjf2WNwAGGyTuAFbbTgX1RPLt/3Wbm68x3IGcX5Cl75CMmgT6WlNwLQ2tCCWfqYPpypjaf2xA==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.ValueTuple": { + "type": "CentralTransitive", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + } + }, + ".NETStandard,Version=v2.0": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "MySqlConnector": { + "type": "Direct", + "requested": "[2.3.5, )", + "resolved": "2.3.5", + "contentHash": "AmEfUPkFl+Ev6jJ8Dhns3CYHBfD12RHzGYWuLt6DfG6/af6YvOMyPz74ZPPjBYQGRJkumD2Z48Kqm8s5DJuhLA==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "7.0.1", + "System.Diagnostics.DiagnosticSource": "7.0.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "7.0.1", + "contentHash": "pkeBFx0vqMW/A3aUVHh7MPu3WkBhaVlezhSZeb1c9XD0vUReYH1TLFSy5MxJgZfmz5LZzYoErMorlYZiwpOoNA==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "7.0.2", + "contentHash": "hYr3I9N9811e0Bjf2WNwAGGyTuAFbbTgX1RPLt/3Wbm68x3IGcX5Cl75CMmgT6WlNwLQ2tCCWfqYPpypjaf2xA==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + } + }, + ".NETStandard,Version=v2.1": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "MySqlConnector": { + "type": "Direct", + "requested": "[2.3.5, )", + "resolved": "2.3.5", + "contentHash": "AmEfUPkFl+Ev6jJ8Dhns3CYHBfD12RHzGYWuLt6DfG6/af6YvOMyPz74ZPPjBYQGRJkumD2Z48Kqm8s5DJuhLA==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "7.0.1", + "System.Diagnostics.DiagnosticSource": "7.0.2" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "7.0.1", + "contentHash": "pkeBFx0vqMW/A3aUVHh7MPu3WkBhaVlezhSZeb1c9XD0vUReYH1TLFSy5MxJgZfmz5LZzYoErMorlYZiwpOoNA==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "7.0.2", + "contentHash": "hYr3I9N9811e0Bjf2WNwAGGyTuAFbbTgX1RPLt/3Wbm68x3IGcX5Cl75CMmgT6WlNwLQ2tCCWfqYPpypjaf2xA==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "distributedlock.core": { + "type": "Project" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.Oracle/DistributedLock.Oracle.csproj b/src/DistributedLock.Oracle/DistributedLock.Oracle.csproj index 24a56f4..32e0600 100644 --- a/src/DistributedLock.Oracle/DistributedLock.Oracle.csproj +++ b/src/DistributedLock.Oracle/DistributedLock.Oracle.csproj @@ -11,7 +11,7 @@ - 1.0.2 + 1.0.3 1.0.0.0 Michael Adelson Provides a distributed lock implementation based on Oracle Database @@ -45,10 +45,10 @@ - - - - + + + + @@ -59,6 +59,5 @@ - \ No newline at end of file diff --git a/src/DistributedLock.Oracle/OracleDbmsLock.cs b/src/DistributedLock.Oracle/OracleDbmsLock.cs index fd81d4d..d536bf3 100644 --- a/src/DistributedLock.Oracle/OracleDbmsLock.cs +++ b/src/DistributedLock.Oracle/OracleDbmsLock.cs @@ -13,10 +13,10 @@ internal class OracleDbmsLock : IDbSynchronizationStrategy private const int MaxWaitSeconds = 32767; private const int MaxTimeoutSeconds = MaxWaitSeconds - 1; - public static readonly OracleDbmsLock SharedLock = new OracleDbmsLock(Mode.Shared), - UpdateLock = new OracleDbmsLock(Mode.Update), - ExclusiveLock = new OracleDbmsLock(Mode.Exclusive), - UpgradeLock = new OracleDbmsLock(Mode.Exclusive, isUpgrade: true); + public static readonly OracleDbmsLock SharedLock = new(Mode.Shared), + UpdateLock = new(Mode.Update), + ExclusiveLock = new(Mode.Exclusive), + UpgradeLock = new(Mode.Exclusive, isUpgrade: true); private static readonly object Cookie = new(); diff --git a/src/DistributedLock.Oracle/packages.lock.json b/src/DistributedLock.Oracle/packages.lock.json new file mode 100644 index 0000000..3d6d09d --- /dev/null +++ b/src/DistributedLock.Oracle/packages.lock.json @@ -0,0 +1,308 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Oracle.ManagedDataAccess": { + "type": "Direct", + "requested": "[21.13.0, )", + "resolved": "21.13.0", + "contentHash": "3OaqQzmx5aRrjBfPu44BaGy9Jz+NiO8Q7x+jPrSL91nSc/M4JYv6j/aX1dwdq4rlSHAw6Ct9rUsd0z7xjvq0Gw==", + "dependencies": { + "System.Formats.Asn1": "7.0.0", + "System.Text.Json": "6.0.1" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Formats.Asn1": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "+nfpV0afLmvJW8+pLlHxRjz3oZJw4fkyU9MMEaMhCsHi/SN9bGF9q79ROubDiwTiCHezmK0uCWkPP7tGFP/4yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.ValueTuple": "4.5.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "X3cTdM+jna1YyfTUzToW7aVgINFv7R1W4+1+3hua/YCyLjApPoR8fd+2Cep9DbfYjbv+rBx4K6dlmAWEJr9AHg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "6.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "6.0.0", + "System.Threading.Tasks.Extensions": "4.5.4", + "System.ValueTuple": "4.5.0" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.ValueTuple": { + "type": "CentralTransitive", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + } + }, + ".NETStandard,Version=v2.1": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Oracle.ManagedDataAccess.Core": { + "type": "Direct", + "requested": "[3.21.130, )", + "resolved": "3.21.130", + "contentHash": "bXNwPyAaDivO84HEYiegK7r/LleSEfA0nc70bE88wkqd1E0Q1+r/SUbJ51xOK2vk6iHbTSMuhnC79BU8svPBjQ==", + "dependencies": { + "System.Diagnostics.PerformanceCounter": "6.0.1", + "System.DirectoryServices": "6.0.1", + "System.DirectoryServices.Protocols": "6.0.2", + "System.Text.Json": "6.0.1" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "UcSjPsst+DfAdJGVDsu346FX0ci0ah+lw3WRtn18NUwEqRt70HaOQ7lI72vy3+1LxtqI3T5GWwV39rQSrCzAeg==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Diagnostics.PerformanceCounter": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "dDl7Gx3bmSrM2k2ZIm+ucEJnLloZRyvfQF1DvfvATcGF3jtaUBiPvChma+6ZcZzxWMirN3kCywkW7PILphXyMQ==" + }, + "System.DirectoryServices": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "935IbO7h5FDGYxeO3cbx/CuvBBuk/VI8sENlfmXlh1pupNOB3LAGzdYdPY8CawGJFP7KNrHK5eUlsFoz3F6cuA==", + "dependencies": { + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.AccessControl": "6.0.0", + "System.Security.Permissions": "6.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.DirectoryServices.Protocols": { + "type": "Transitive", + "resolved": "6.0.2", + "contentHash": "vDDPWwHn3/DNZ+kPkdXHoada+tKPEC9bVqDOr4hK6HBSP7hGCUTA0Zw6WU5qpGaqa5M1/V+axHMIv+DNEbIf6g==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "X3cTdM+jna1YyfTUzToW7aVgINFv7R1W4+1+3hua/YCyLjApPoR8fd+2Cep9DbfYjbv+rBx4K6dlmAWEJr9AHg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "6.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "6.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.Postgres/DistributedLock.Postgres.csproj b/src/DistributedLock.Postgres/DistributedLock.Postgres.csproj index 97544ee..6e20a5a 100644 --- a/src/DistributedLock.Postgres/DistributedLock.Postgres.csproj +++ b/src/DistributedLock.Postgres/DistributedLock.Postgres.csproj @@ -1,7 +1,7 @@ - netstandard2.0;netstandard2.1;net461 + netstandard2.0;netstandard2.1;net462 Medallion.Threading.Postgres True 4 @@ -11,7 +11,7 @@ - 1.0.5 + 1.1.0 1.0.0.0 Michael Adelson Provides a distributed lock implementation based on Postgresql @@ -45,9 +45,9 @@ - - - + + + @@ -58,6 +58,5 @@ - \ No newline at end of file diff --git a/src/DistributedLock.Postgres/PostgresAdvisoryLock.cs b/src/DistributedLock.Postgres/PostgresAdvisoryLock.cs index 9b6d105..2a8f961 100644 --- a/src/DistributedLock.Postgres/PostgresAdvisoryLock.cs +++ b/src/DistributedLock.Postgres/PostgresAdvisoryLock.cs @@ -44,15 +44,15 @@ private PostgresAdvisoryLock(bool isShared) return null; } - var hasTransaction = await HasTransactionAsync(connection).ConfigureAwait(false); - if (hasTransaction) + // Our acquire command will use SET LOCAL to set up statement timeouts. This lasts until the end + // of the current transaction instead of just the current batch if we're in a transaction. To make sure + // we don't leak those settings, in the case of a transaction we first set up a save point which we can + // later roll back (taking the settings changes with it but NOT the lock). Because we can't confidently + // roll back a save point without knowing that it has been set up, we start the save point in its own + // query before we try-catch + var needsSavePoint = await HasTransactionAsync(connection).ConfigureAwait(false); + if (needsSavePoint) { - // Our acquire command will use SET LOCAL to set up statement timeouts. This lasts until the end - // of the current transaction instead of just the current batch if we're in a transaction. To make sure - // we don't leak those settings, in the case of a transaction we first set up a save point which we can - // later roll back (taking the settings changes with it but NOT the lock). Because we can't confidently - // roll back a save point without knowing that it has been set up, we start the save point in its own - // query before we try-catch using var setSavePointCommand = connection.CreateCommand(); setSavePointCommand.SetCommandText("SAVEPOINT " + SavePointName); await setSavePointCommand.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false); @@ -60,20 +60,20 @@ private PostgresAdvisoryLock(bool isShared) using var acquireCommand = this.CreateAcquireCommand(connection, key, timeout); - object acquireCommandResult; + object? acquireCommandResult; try { acquireCommandResult = await acquireCommand.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false); } catch (Exception ex) { - await RollBackTransactionTimeoutVariablesIfNeededAsync().ConfigureAwait(false); + await RollBackTransactionTimeoutVariablesIfNeededAsync(acquired: false).ConfigureAwait(false); if (ex is PostgresException postgresException) { switch (postgresException.SqlState) { - // lock_timeout error code from https://www.postgresql.org/docs/10/errcodes-appendix.html + // lock_timeout error code from https://www.postgresql.org/docs/16/errcodes-appendix.html case "55P03": // Even though we hit a lock timeout, an underlying race condition in Postgres means that we might actually // have acquired the lock right before timing out. To account for this, we simply re-check whether we are @@ -83,13 +83,18 @@ private PostgresAdvisoryLock(bool isShared) return await this.IsHoldingLockAsync(connection, key, CancellationToken.None).ConfigureAwait(false) ? Cookie : null; - // deadlock_detected error code from https://www.postgresql.org/docs/10/errcodes-appendix.html + // deadlock_detected error code from https://www.postgresql.org/docs/16/errcodes-appendix.html case "40P01": throw new DeadlockException($"The request for the distributed lock failed with exit code '{postgresException.SqlState}' (deadlock_detected)", ex); } } - if (ex is OperationCanceledException && cancellationToken.IsCancellationRequested) + if (ex is OperationCanceledException + && cancellationToken.IsCancellationRequested + // There's no way to explicitly release transaction-scoped locks other than a rollback; in our case + // RollBackTransactionTimeoutVariablesIfNeededAsync will have already released by rolling back the savepoint. + // Furthermore the caller will proceed to dispose the transaction. + && !UseTransactionScopedLock(connection)) { // if we bailed in the middle of an acquire, make sure we didn't leave a lock behind await this.ReleaseAsync(connection, key, isTry: true).ConfigureAwait(false); @@ -98,20 +103,31 @@ private PostgresAdvisoryLock(bool isShared) throw; } - await RollBackTransactionTimeoutVariablesIfNeededAsync().ConfigureAwait(false); + var acquired = acquireCommandResult switch + { + DBNull _ => true, // indicates we called pg_advisory_lock and not pg_try_advisory_lock + null => true, // Npgsql 8 returns null instead of DBNull + false => false, + true => true, + _ => default(bool?) + }; + + await RollBackTransactionTimeoutVariablesIfNeededAsync(acquired: acquired == true).ConfigureAwait(false); - return acquireCommandResult switch + return acquired switch { - DBNull _ => Cookie, // indicates we called pg_advisory_lock and not pg_try_advisory_lock - null => Cookie, // Npgsql 8 returns null instead of DBNull false => null, true => Cookie, - _ => throw new InvalidOperationException($"Unexpected value '{acquireCommandResult}' from acquire command") + null => throw new InvalidOperationException($"Unexpected value '{acquireCommandResult}' from acquire command") }; - async ValueTask RollBackTransactionTimeoutVariablesIfNeededAsync() + async ValueTask RollBackTransactionTimeoutVariablesIfNeededAsync(bool acquired) { - if (hasTransaction) + if (needsSavePoint + // For transaction scoped locks, we can't roll back the save point on success because that will roll + // back our hold on the lock. It's ok to "leak" the savepoint in that case because it's an internally-owned + // transaction/connection and the savepoint will be cleaned up with the disposal of the transaction. + && !(acquired && UseTransactionScopedLock(connection))) { // attempt to clear the timeout variables we set using var rollBackSavePointCommand = connection.CreateCommand(); @@ -134,7 +150,7 @@ JOIN pg_catalog.pg_database d AND l.pid = pg_catalog.pg_backend_pid() AND d.datname = pg_catalog.current_database()" ); - return (long)await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false) != 0; + return (long)(await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false))! != 0; } private DatabaseCommand CreateAcquireCommand(DatabaseConnection connection, PostgresAdvisoryLockKey key, TimeoutValue timeout) @@ -153,7 +169,9 @@ private DatabaseCommand CreateAcquireCommand(DatabaseConnection connection, Post var isTry = timeout.IsZero; commandText.Append("pg_catalog.pg"); if (isTry) { commandText.Append("_try"); } - commandText.Append("_advisory_lock"); + commandText.Append("_advisory"); + if (UseTransactionScopedLock(connection)) { commandText.Append("_xact"); } + commandText.Append("_lock"); if (this._isShared) { commandText.Append("_shared"); } commandText.Append('(').Append(AddKeyParametersAndGetKeyArguments(command, key)).Append(')') .Append(" AS result"); @@ -189,9 +207,11 @@ public ValueTask ReleaseAsync(DatabaseConnection connection, string resourceName private async ValueTask ReleaseAsync(DatabaseConnection connection, PostgresAdvisoryLockKey key, bool isTry) { + Invariant.Require(!UseTransactionScopedLock(connection)); + using var command = connection.CreateCommand(); command.SetCommandText($"SELECT pg_catalog.pg_advisory_unlock{(this._isShared ? "_shared" : string.Empty)}({AddKeyParametersAndGetKeyArguments(command, key)})"); - var result = (bool)await command.ExecuteScalarAsync(CancellationToken.None).ConfigureAwait(false); + var result = (bool)(await command.ExecuteScalarAsync(CancellationToken.None).ConfigureAwait(false))!; if (!isTry && !result) { throw new InvalidOperationException("Attempted to release a lock that was not held"); @@ -214,6 +234,12 @@ private static string AddKeyParametersAndGetKeyArguments(DatabaseCommand command } } + private static bool UseTransactionScopedLock(DatabaseConnection connection) => + // This implementation (similar to what we do for SQL Server) is based on the fact that we only create transactions on + // internally-owned connections when doing transaction-scoped locking, and we only support transaction-scoped locking on + // internally-owned connections (since there's no explicit release). + !connection.IsExernallyOwned && connection.HasTransaction; + private static string AddPGLocksFilterParametersAndGetFilterExpression(DatabaseCommand command, PostgresAdvisoryLockKey key) { // From https://www.postgresql.org/docs/12/view-pg-locks.html diff --git a/src/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.cs b/src/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.cs index 8ea2551..a75fee0 100644 --- a/src/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.cs +++ b/src/DistributedLock.Postgres/PostgresConnectionOptionsBuilder.cs @@ -1,4 +1,5 @@ using Medallion.Threading.Internal; +using System.Data; namespace Medallion.Threading.Postgres; @@ -8,7 +9,7 @@ namespace Medallion.Threading.Postgres; public sealed class PostgresConnectionOptionsBuilder { private TimeoutValue? _keepaliveCadence; - private bool? _useMultiplexing; + private bool? _useTransaction, _useMultiplexing; internal PostgresConnectionOptionsBuilder() { } @@ -26,6 +27,23 @@ public PostgresConnectionOptionsBuilder KeepaliveCadence(TimeSpan keepaliveCaden return this; } + /// + /// Whether the synchronization should use a transaction scope rather than a session scope. Defaults to false. + /// + /// Synchronizing based on a transaction is necessary to do distributed locking with some pgbouncer configurations + /// (see https://github.com/madelson/DistributedLock/issues/168#issuecomment-1823277173). It may also be marginally less + /// expensive than using a connection for a single lock because releasing requires only disposing the + /// underlying . + /// + /// The disadvantage of this strategy is that it is incompatible with and therefore + /// gives up the advantages of that approach. + /// + public PostgresConnectionOptionsBuilder UseTransaction(bool useTransaction = true) + { + this._useTransaction = useTransaction; + return this; + } + /// /// This mode takes advantage of the fact that while "holding" a lock (or other synchronization primitive) /// a connection is essentially idle. Thus, rather than creating a new connection for each held lock it is @@ -48,7 +66,7 @@ public PostgresConnectionOptionsBuilder UseMultiplexing(bool useMultiplexing = t return this; } - internal static (TimeoutValue keepaliveCadence, bool useMultiplexing) GetOptions(Action? optionsBuilder) + internal static (TimeoutValue keepaliveCadence, bool useTransaction, bool useMultiplexing) GetOptions(Action? optionsBuilder) { PostgresConnectionOptionsBuilder? options; if (optionsBuilder != null) @@ -62,8 +80,14 @@ internal static (TimeoutValue keepaliveCadence, bool useMultiplexing) GetOptions } var keepaliveCadence = options?._keepaliveCadence ?? Timeout.InfiniteTimeSpan; - var useMultiplexing = options?._useMultiplexing ?? true; + var useTransaction = options?._useTransaction ?? false; + var useMultiplexing = options?._useMultiplexing ?? !options?._useTransaction ?? true; + + if (useMultiplexing && useTransaction) + { + throw new ArgumentException(nameof(UseTransaction) + ": is not compatible with " + nameof(UseMultiplexing)); + } - return (keepaliveCadence, useMultiplexing); + return (keepaliveCadence, useTransaction, useMultiplexing); } } diff --git a/src/DistributedLock.Postgres/PostgresDistributedLock.cs b/src/DistributedLock.Postgres/PostgresDistributedLock.cs index 4bef94c..fae80b3 100644 --- a/src/DistributedLock.Postgres/PostgresDistributedLock.cs +++ b/src/DistributedLock.Postgres/PostgresDistributedLock.cs @@ -49,14 +49,11 @@ internal static IDbDistributedLock CreateInternalLock(PostgresAdvisoryLockKey ke { if (connectionString == null) { throw new ArgumentNullException(nameof(connectionString)); } - var (keepaliveCadence, useMultiplexing) = PostgresConnectionOptionsBuilder.GetOptions(options); + var (keepaliveCadence, useTransaction, useMultiplexing) = PostgresConnectionOptionsBuilder.GetOptions(options); - if (useMultiplexing) - { - return new OptimisticConnectionMultiplexingDbDistributedLock(key.ToString(), connectionString, PostgresMultiplexedConnectionLockPool.Instance, keepaliveCadence); - } - - return new DedicatedConnectionOrTransactionDbDistributedLock(key.ToString(), () => new PostgresDatabaseConnection(connectionString), useTransaction: false, keepaliveCadence); + return useMultiplexing + ? new OptimisticConnectionMultiplexingDbDistributedLock(key.ToString(), connectionString, PostgresMultiplexedConnectionLockPool.Instance, keepaliveCadence) + : new DedicatedConnectionOrTransactionDbDistributedLock(key.ToString(), () => new PostgresDatabaseConnection(connectionString), useTransaction: useTransaction, keepaliveCadence); } internal static IDbDistributedLock CreateInternalLock(PostgresAdvisoryLockKey key, IDbConnection connection) diff --git a/src/DistributedLock.Postgres/PublicAPI.Shipped.txt b/src/DistributedLock.Postgres/PublicAPI.Shipped.txt index 43fce91..72be84e 100644 --- a/src/DistributedLock.Postgres/PublicAPI.Shipped.txt +++ b/src/DistributedLock.Postgres/PublicAPI.Shipped.txt @@ -8,6 +8,7 @@ Medallion.Threading.Postgres.PostgresAdvisoryLockKey.PostgresAdvisoryLockKey(str Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder.KeepaliveCadence(System.TimeSpan keepaliveCadence) -> Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder! Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder.UseMultiplexing(bool useMultiplexing = true) -> Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder! +Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder.UseTransaction(bool useTransaction = true) -> Medallion.Threading.Postgres.PostgresConnectionOptionsBuilder! Medallion.Threading.Postgres.PostgresDistributedLock Medallion.Threading.Postgres.PostgresDistributedLock.Acquire(System.TimeSpan? timeout = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> Medallion.Threading.Postgres.PostgresDistributedLockHandle! Medallion.Threading.Postgres.PostgresDistributedLock.AcquireAsync(System.TimeSpan? timeout = null, System.Threading.CancellationToken cancellationToken = default(System.Threading.CancellationToken)) -> System.Threading.Tasks.ValueTask diff --git a/src/DistributedLock.Postgres/packages.lock.json b/src/DistributedLock.Postgres/packages.lock.json new file mode 100644 index 0000000..4fd8add --- /dev/null +++ b/src/DistributedLock.Postgres/packages.lock.json @@ -0,0 +1,513 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Npgsql": { + "type": "Direct", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "MuJzLoWCaQhQAR3oh66YR0Ir6mxuezncGX3f8wxvAc21g0+9HICktJQlqMoODhxztZKXE5k9GxRxqUAN+vPb4g==", + "dependencies": { + "Microsoft.Bcl.HashCode": "1.1.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "System.Collections.Immutable": "8.0.0", + "System.Diagnostics.DiagnosticSource": "8.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Json": "8.0.0", + "System.Threading.Channels": "8.0.0" + } + }, + "Microsoft.Bcl.HashCode": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "MalY0Y/uM/LjXtHfX/26l2VtN4LDNZ2OE3aumNOHDLsT4fNYy2hiHXI4CXCqKpNUNm7iJ2brrc4J89UdaL56FA==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4", + "System.ValueTuple": "4.5.0" + } + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.ValueTuple": { + "type": "CentralTransitive", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + } + }, + ".NETStandard,Version=v2.0": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Npgsql": { + "type": "Direct", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "MuJzLoWCaQhQAR3oh66YR0Ir6mxuezncGX3f8wxvAc21g0+9HICktJQlqMoODhxztZKXE5k9GxRxqUAN+vPb4g==", + "dependencies": { + "Microsoft.Bcl.HashCode": "1.1.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "System.Collections.Immutable": "8.0.0", + "System.Diagnostics.DiagnosticSource": "8.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Json": "8.0.0", + "System.Threading.Channels": "8.0.0" + } + }, + "Microsoft.Bcl.HashCode": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "MalY0Y/uM/LjXtHfX/26l2VtN4LDNZ2OE3aumNOHDLsT4fNYy2hiHXI4CXCqKpNUNm7iJ2brrc4J89UdaL56FA==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + } + }, + ".NETStandard,Version=v2.1": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Npgsql": { + "type": "Direct", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "MuJzLoWCaQhQAR3oh66YR0Ir6mxuezncGX3f8wxvAc21g0+9HICktJQlqMoODhxztZKXE5k9GxRxqUAN+vPb4g==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "System.Collections.Immutable": "8.0.0", + "System.Diagnostics.DiagnosticSource": "8.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Json": "8.0.0", + "System.Threading.Channels": "8.0.0" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.Redis/DistributedLock.Redis.csproj b/src/DistributedLock.Redis/DistributedLock.Redis.csproj index 7553a20..334d7bd 100644 --- a/src/DistributedLock.Redis/DistributedLock.Redis.csproj +++ b/src/DistributedLock.Redis/DistributedLock.Redis.csproj @@ -1,7 +1,7 @@ - net461;netstandard2.0;netstandard2.1 + net462;netstandard2.0;netstandard2.1 Medallion.Threading.Redis True 4 @@ -11,7 +11,7 @@ - 1.0.2 + 1.0.3 1.0.0.0 Michael Adelson Provides distributed locking primitives based on Redis @@ -49,19 +49,17 @@ - - + + all - - - + + - \ No newline at end of file diff --git a/src/DistributedLock.Redis/Primitives/RedisMutexPrimitive.cs b/src/DistributedLock.Redis/Primitives/RedisMutexPrimitive.cs index 51b3c2d..b65d1b7 100644 --- a/src/DistributedLock.Redis/Primitives/RedisMutexPrimitive.cs +++ b/src/DistributedLock.Redis/Primitives/RedisMutexPrimitive.cs @@ -19,11 +19,11 @@ public RedisMutexPrimitive(RedisKey key, RedisValue lockId, RedLockTimeouts time public TimeoutValue AcquireTimeout => this._timeouts.AcquireTimeout; - private static readonly RedisScript ReleaseScript = new RedisScript(@" - if redis.call('get', @key) == @lockId then - return redis.call('del', @key) - end - return 0", + private static readonly RedisScript ReleaseScript = new(@" + if redis.call('get', @key) == @lockId then + return redis.call('del', @key) + end + return 0", p => new { key = p._key, lockId = p._lockId } ); @@ -35,13 +35,15 @@ public bool TryAcquire(IDatabase database) => public Task TryAcquireAsync(IDatabaseAsync database) => database.StringSetAsync(this._key, this._lockId, this._timeouts.Expiry.TimeSpan, When.NotExists, CommandFlags.DemandMaster); - private static readonly RedisScript ExtendScript = new RedisScript(@" - if redis.call('get', @key) == @lockId then - return redis.call('pexpire', @key, @expiryMillis) - end - return 0", + private static readonly RedisScript ExtendScript = new(@" + if redis.call('get', @key) == @lockId then + return redis.call('pexpire', @key, @expiryMillis) + end + return 0", p => new { key = p._key, lockId = p._lockId, expiryMillis = p._timeouts.Expiry.InMilliseconds } ); public Task TryExtendAsync(IDatabaseAsync database) => ExtendScript.ExecuteAsync(database, this).AsBooleanTask(); + + public bool IsConnected(IDatabase database) => database.IsConnected(this._key, CommandFlags.DemandMaster); } diff --git a/src/DistributedLock.Redis/Primitives/RedisReaderWriterLockPrimitives.cs b/src/DistributedLock.Redis/Primitives/RedisReaderWriterLockPrimitives.cs index 06d4025..d239876 100644 --- a/src/DistributedLock.Redis/Primitives/RedisReaderWriterLockPrimitives.cs +++ b/src/DistributedLock.Redis/Primitives/RedisReaderWriterLockPrimitives.cs @@ -24,7 +24,7 @@ public RedisReadLockPrimitive(RedisKey readerKey, RedisKey writerKey, RedLockTim /// /// Just remove our ID from the reader set (noop if it wasn't there or the set DNE) /// - private static readonly RedisScript ReleaseReadScript = new RedisScript( + private static readonly RedisScript ReleaseReadScript = new( @"redis.call('srem', @readerKey, @lockId)", p => new { readerKey = p._readerKey, lockId = p._lockId } ); @@ -39,7 +39,7 @@ public RedisReadLockPrimitive(RedisKey readerKey, RedisKey writerKey, RedLockTim /// /// Then, extend the reader set TTL to be at least our expiry (at least because other readers might be operating with a longer expiry) /// - private static readonly RedisScript TryExtendReadScript = new RedisScript(@" + private static readonly RedisScript TryExtendReadScript = new(@" if redis.call('sismember', @readerKey, @lockId) == 0 then return 0 end @@ -60,7 +60,7 @@ public RedisReadLockPrimitive(RedisKey readerKey, RedisKey writerKey, RedLockTim /// Then, add our ID to the reader set, creating it if it does not exist. Then, extend the TTL /// of the reader set to be at least our expiry. Return success. /// - private static readonly RedisScript TryAcquireReadScript = new RedisScript($@" + private static readonly RedisScript TryAcquireReadScript = new($@" if redis.call('exists', @writerKey) == 1 then return 0 end @@ -75,6 +75,8 @@ public RedisReadLockPrimitive(RedisKey readerKey, RedisKey writerKey, RedLockTim public Task TryAcquireAsync(IDatabaseAsync database) => TryAcquireReadScript.ExecuteAsync(database, this).AsBooleanTask(); public bool TryAcquire(IDatabase database) => (bool)TryAcquireReadScript.Execute(database, this); + + public bool IsConnected(IDatabase database) => database.IsConnected(this._readerKey, CommandFlags.DemandMaster); } internal class RedisWriterWaitingPrimitive : RedisMutexPrimitive @@ -122,7 +124,7 @@ public RedisWriteLockPrimitive( /// /// Finally, return failure. /// - private static readonly RedisScript TryAcquireWriteScript = new RedisScript($@" + private static readonly RedisScript TryAcquireWriteScript = new($@" local writerValue = redis.call('get', @writerKey) if writerValue == false or writerValue == @lockId .. '{RedisWriterWaitingPrimitive.LockIdSuffix}' then if redis.call('scard', @readerKey) == 0 then @@ -141,4 +143,6 @@ public RedisWriteLockPrimitive( public Task TryAcquireAsync(IDatabaseAsync database) => TryAcquireWriteScript.ExecuteAsync(database, this).AsBooleanTask(); public Task TryExtendAsync(IDatabaseAsync database) => this._mutexPrimitive.TryExtendAsync(database); + + public bool IsConnected(IDatabase database) => database.IsConnected(this._writerKey, CommandFlags.DemandMaster); } diff --git a/src/DistributedLock.Redis/Primitives/RedisScript.cs b/src/DistributedLock.Redis/Primitives/RedisScript.cs index 569264a..efbcfbb 100644 --- a/src/DistributedLock.Redis/Primitives/RedisScript.cs +++ b/src/DistributedLock.Redis/Primitives/RedisScript.cs @@ -4,24 +4,17 @@ namespace Medallion.Threading.Redis.Primitives; -internal class RedisScript +internal class RedisScript(string script, Func parameters) { - private readonly LuaScript _script; - private readonly Func _parameters; - - public RedisScript(string script, Func parameters) - { - this._script = LuaScript.Prepare(RemoveExtraneousWhitespace(script)); - this._parameters = parameters; - } + private readonly LuaScript _script = LuaScript.Prepare(RemoveExtraneousWhitespace(script)); public RedisResult Execute(IDatabase database, TArgument argument, bool fireAndForget = false) => - // database.ScriptEvaluate must be called instead of _script.Evaluate in order to respect the database's key prefix - database.ScriptEvaluate(this._script, this._parameters(argument), flags: RedLockHelper.GetCommandFlags(fireAndForget)); + // database.ScriptEvaluate must be called instead of script.Evaluate in order to respect the database's key prefix + database.ScriptEvaluate(this._script, parameters(argument), flags: RedLockHelper.GetCommandFlags(fireAndForget)); public Task ExecuteAsync(IDatabaseAsync database, TArgument argument, bool fireAndForget = false) => - // database.ScriptEvaluate must be called instead of _script.Evaluate in order to respect the database's key prefix - database.ScriptEvaluateAsync(this._script, this._parameters(argument), flags: RedLockHelper.GetCommandFlags(fireAndForget)); + // database.ScriptEvaluate must be called instead of script.Evaluate in order to respect the database's key prefix + database.ScriptEvaluateAsync(this._script, parameters(argument), flags: RedLockHelper.GetCommandFlags(fireAndForget)); // send the smallest possible script to the server private static string RemoveExtraneousWhitespace(string script) => Regex.Replace(script.Trim(), @"\s+", " "); diff --git a/src/DistributedLock.Redis/Primitives/RedisSemaphorePrimitive.cs b/src/DistributedLock.Redis/Primitives/RedisSemaphorePrimitive.cs index 39297e4..bae8194 100644 --- a/src/DistributedLock.Redis/Primitives/RedisSemaphorePrimitive.cs +++ b/src/DistributedLock.Redis/Primitives/RedisSemaphorePrimitive.cs @@ -51,7 +51,7 @@ public void Release(IDatabase database, bool fireAndForget) => public Task ReleaseAsync(IDatabaseAsync database, bool fireAndForget) => database.SortedSetRemoveAsync(this._key, this._lockId, RedLockHelper.GetCommandFlags(fireAndForget)); - private static readonly RedisScript AcquireScript = new RedisScript($@" + private static readonly RedisScript AcquireScript = new($@" {GetNowMillisScriptFragment} redis.call('zremrangebyscore', @key, '-inf', nowMillis) if redis.call('zcard', @key) < tonumber(@maxCount) then @@ -67,7 +67,7 @@ public Task ReleaseAsync(IDatabaseAsync database, bool fireAndForget) => public Task TryAcquireAsync(IDatabaseAsync database) => AcquireScript.ExecuteAsync(database, this).AsBooleanTask(); - private static readonly RedisScript ExtendScript = new RedisScript($@" + private static readonly RedisScript ExtendScript = new($@" {GetNowMillisScriptFragment} local result = redis.call('zadd', @key, 'XX', 'CH', nowMillis + tonumber(@expiryMillis), @lockId) {RenewSetScriptFragment} @@ -76,4 +76,6 @@ public Task ReleaseAsync(IDatabaseAsync database, bool fireAndForget) => ); public Task TryExtendAsync(IDatabaseAsync database) => ExtendScript.ExecuteAsync(database, this).AsBooleanTask(); + + public bool IsConnected(IDatabase database) => database.IsConnected(this._key, CommandFlags.DemandMaster); } diff --git a/src/DistributedLock.Redis/RedLock/RedLockAcquire.cs b/src/DistributedLock.Redis/RedLock/RedLockAcquire.cs index a103285..9357570 100644 --- a/src/DistributedLock.Redis/RedLock/RedLockAcquire.cs +++ b/src/DistributedLock.Redis/RedLock/RedLockAcquire.cs @@ -9,6 +9,7 @@ internal interface IRedLockAcquirableSynchronizationPrimitive : IRedLockReleasab TimeoutValue AcquireTimeout { get; } Task TryAcquireAsync(IDatabaseAsync database); bool TryAcquire(IDatabase database); + bool IsConnected(IDatabase database); } /// @@ -77,7 +78,7 @@ public RedLockAcquire( } else { - (releaseTasks ??= new List()) + (releaseTasks ??= []) .Add(Helpers.SafeCreateTask(state => state.primitive.ReleaseAsync(state.Key, fireAndForget: true), (primitive, kvp.Key))); } } @@ -103,7 +104,8 @@ private async Task WaitForAcquireAsync(IReadOnlyDictionary WaitForAcquireAsync(IReadOnlyDictionary 1, "should be more than just timeout left"); } + + // MA: this behavior is non-trivial and worth a detailed explanation. Basically, StackExchange.Redis 2.5.27 switched + // the behavior when firing commands against a disconnected database so that those commands would backlog for a period waiting for + // a reconnect rather than failing fast (fail fast is still a non-default option on ConnectionMultiplexer, but we don't want to + // require that). + // + // While this behavior generally makes sense, it creates long delays for the RedLock algorithm. For example, imagine + // a case where processes 1 and 2 are locking against servers A, B, and C when C is down. If process 1 acquires on A and process 2 acquires + // on B, then C is left casting the winning vote and for that to happen both threads must wait for the full connection timeout to observe + // the issue and declare a failed acquire. + // + // The delays caused by this are quite evident in our TestParallelism() case in the 2x1 scenario emulating a downed server: they are significant + // enough to fail the test! + // + // The fix I've implemented is to bypass the backlog via a connectivity check when it comes to the server casting the "deciding vote" in a multi-server + // scenario. That way, the case above is resolved quickly because both proceses will see that C is disconnected and fail the current acquire without + // waiting. Note that this is always a no-op in the single-server scenario. + // + // The current approach DOES NOT handle the case where the deciding vote is down to multiple servers all of which are down. We could implement this + // at the cost of additional complexity, but currently I don't see that as worthwhile since the scenario should be much less common and more problematic + // anyway. + // + // Finally, note that while this behavior could be extended to all RedLock operations (extend, release), I don't see that as valuable since only acquire is + // subject to contention in normal scenarios, so the optimization isn't worth anything elsewhere. + // + // RELEVANT LINKS: + // https://github.com/madelson/DistributedLock/pull/173#discussion_r1342236087 + // https://github.com/StackExchange/StackExchange.Redis/issues/2645 + Task? TryResolveDisconnectedDatabaseAsFaulted(RedLockAcquire @this) + { + // First, check to see if (a) we have at least 1 success/failure and (b) one more would be decisive. If not, bail. + if (!((successCount > 0 && RedLockHelper.HasSufficientSuccesses(successCount + 1, @this._databases.Count)) + || (failCount > 0 && RedLockHelper.HasTooManyFailuresOrFaults(failCount + 1, @this._databases.Count)))) + { + return null; + } + + // Iterate over the tasks to see if all outstanding tasks are disconnected. If so, pick one to resolve + Task? toResolve = null; + foreach (var kvp in tryAcquireTasks) + { + if (incompleteTasks.Contains(kvp.Value)) + { + if (kvp.Value.IsCompleted) + { + return null; + } + if (toResolve is null && !@this._primitive.IsConnected(kvp.Key)) + { + toResolve = kvp.Value; + // don't return here because if another task is completed we want that to take precedence + } + } + } + + if (toResolve is null) { return null; } + + // Remove this here because we'll be replacing it with a resolved task so the later call to + // incompleteTasks.Remove() will noop + incompleteTasks.Remove(toResolve); + return Task.FromException(new RedisException("Database is disconnected")); + } } /// diff --git a/src/DistributedLock.Redis/RedLock/RedLockHelper.cs b/src/DistributedLock.Redis/RedLock/RedLockHelper.cs index 8883662..5b819e5 100644 --- a/src/DistributedLock.Redis/RedLock/RedLockHelper.cs +++ b/src/DistributedLock.Redis/RedLock/RedLockHelper.cs @@ -44,15 +44,16 @@ public static void FireAndForgetReleaseUponCompletion(IRedLockReleasableSynchron { if (ReturnedFalse(acquireOrRenewTask)) { return; } - acquireOrRenewTask.ContinueWith(async (t, state) => + acquireOrRenewTask.ContinueWith(static async (t, state) => { // don't clean up if we know we failed if (!ReturnedFalse(t)) { - await primitive.ReleaseAsync((IDatabase) state, fireAndForget: true).ConfigureAwait(false); + var (primitive, database) = (Tuple)state; + await primitive.ReleaseAsync(database, fireAndForget: true).ConfigureAwait(false); } }, - state: database + state: Tuple.Create(primitive, database) ); } diff --git a/src/DistributedLock.Redis/RedLock/RedLockRelease.cs b/src/DistributedLock.Redis/RedLock/RedLockRelease.cs index 414b2a1..ce3e383 100644 --- a/src/DistributedLock.Redis/RedLock/RedLockRelease.cs +++ b/src/DistributedLock.Redis/RedLock/RedLockRelease.cs @@ -12,23 +12,14 @@ internal interface IRedLockReleasableSynchronizationPrimitive /// /// Implements the release operation in the RedLock algorithm. See https://redis.io/topics/distlock /// -internal readonly struct RedLockRelease +internal readonly struct RedLockRelease( + IRedLockReleasableSynchronizationPrimitive primitive, + IReadOnlyDictionary> tryAcquireOrRenewTasks) { - private readonly IRedLockReleasableSynchronizationPrimitive _primitive; - private readonly IReadOnlyDictionary> _tryAcquireOrRenewTasks; - - public RedLockRelease( - IRedLockReleasableSynchronizationPrimitive primitive, - IReadOnlyDictionary> tryAcquireOrRenewTasks) - { - this._primitive = primitive; - this._tryAcquireOrRenewTasks = tryAcquireOrRenewTasks; - } - public async ValueTask ReleaseAsync() { var isSynchronous = SyncViaAsync.IsSynchronous; - var unreleasedTryAcquireOrRenewTasks = this._tryAcquireOrRenewTasks.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); + var unreleasedTryAcquireOrRenewTasks = tryAcquireOrRenewTasks.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); List? releaseExceptions = null; var successCount = 0; @@ -40,10 +31,12 @@ public async ValueTask ReleaseAsync() while (true) { var releaseableDatabases = unreleasedTryAcquireOrRenewTasks.Where(kvp => kvp.Value.IsCompleted) - // work through non-faulted tasks first - .OrderByDescending(kvp => kvp.Value.Status == TaskStatus.RanToCompletion) - // then start with failed since no action is required to release those - .ThenBy(kvp => kvp.Value.Status == TaskStatus.RanToCompletion && kvp.Value.Result) + // work through completed tasks first + .OrderByDescending(kvp => kvp.Value.IsCompleted) + // among those prioritize successful completions since faults are likely to be slow to process + .ThenByDescending(kvp => kvp.Value.Status == TaskStatus.RanToCompletion) + // among those prioritize failed (not faulted) acquisitions since those require no work to release + .ThenByDescending(kvp => RedLockHelper.ReturnedFalse(kvp.Value)) .Select(kvp => kvp.Key) .ToArray(); foreach (var db in releaseableDatabases) @@ -60,13 +53,13 @@ public async ValueTask ReleaseAsync() { try { - if (isSynchronous) { this._primitive.Release(db, fireAndForget: false); } - else { await this._primitive.ReleaseAsync(db, fireAndForget: false).ConfigureAwait(false); } + if (isSynchronous) { primitive.Release(db, fireAndForget: false); } + else { await primitive.ReleaseAsync(db, fireAndForget: false).ConfigureAwait(false); } ++successCount; } catch (Exception ex) { - (releaseExceptions ??= new List()).Add(ex); + (releaseExceptions ??= []).Add(ex); ++faultCount; if (RedLockHelper.HasTooManyFailuresOrFaults(faultCount, databaseCount)) { @@ -90,7 +83,7 @@ public async ValueTask ReleaseAsync() { foreach (var kvp in unreleasedTryAcquireOrRenewTasks) { - RedLockHelper.FireAndForgetReleaseUponCompletion(this._primitive, kvp.Key, kvp.Value); + RedLockHelper.FireAndForgetReleaseUponCompletion(primitive, kvp.Key, kvp.Value); } } } diff --git a/src/DistributedLock.Redis/RedisDistributedSynchronizationProvider.cs b/src/DistributedLock.Redis/RedisDistributedSynchronizationProvider.cs index 8089313..af74076 100644 --- a/src/DistributedLock.Redis/RedisDistributedSynchronizationProvider.cs +++ b/src/DistributedLock.Redis/RedisDistributedSynchronizationProvider.cs @@ -37,7 +37,7 @@ public RedisDistributedSynchronizationProvider(IEnumerable databases, /// /// Creates a using the given . /// - public RedisDistributedLock CreateLock(RedisKey key) => new RedisDistributedLock(key, this._databases, this._options); + public RedisDistributedLock CreateLock(RedisKey key) => new(key, this._databases, this._options); IDistributedLock IDistributedLockProvider.CreateLock(string name) => this.CreateLock(name); @@ -45,7 +45,7 @@ public RedisDistributedSynchronizationProvider(IEnumerable databases, /// Creates a using the given . /// public RedisDistributedReaderWriterLock CreateReaderWriterLock(string name) => - new RedisDistributedReaderWriterLock(name, this._databases, this._options); + new(name, this._databases, this._options); IDistributedReaderWriterLock IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string name) => this.CreateReaderWriterLock(name); @@ -53,7 +53,7 @@ IDistributedReaderWriterLock IDistributedReaderWriterLockProvider.CreateReaderWr /// /// Creates a using the provided and . /// - public RedisDistributedSemaphore CreateSemaphore(RedisKey key, int maxCount) => new RedisDistributedSemaphore(key, maxCount, this._databases[0], this._options); + public RedisDistributedSemaphore CreateSemaphore(RedisKey key, int maxCount) => new(key, maxCount, this._databases[0], this._options); IDistributedSemaphore IDistributedSemaphoreProvider.CreateSemaphore(string name, int maxCount) => this.CreateSemaphore(name, maxCount); diff --git a/src/DistributedLock.Redis/packages.lock.json b/src/DistributedLock.Redis/packages.lock.json new file mode 100644 index 0000000..85f211f --- /dev/null +++ b/src/DistributedLock.Redis/packages.lock.json @@ -0,0 +1,423 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Nullable": { + "type": "Direct", + "requested": "[1.3.1, )", + "resolved": "1.3.1", + "contentHash": "Mk4ZVDfAORTjvckQprCSehi1XgOAAlk5ez06Va/acRYEloN9t6d6zpzJRn5MEq7+RnagyFIq9r+kbWzLGd+6QA==" + }, + "StackExchange.Redis": { + "type": "Direct", + "requested": "[2.7.27, )", + "resolved": "2.7.27", + "contentHash": "Uqc2OQHglqj9/FfGQ6RkKFkZfHySfZlfmbCl+hc+u2I/IqunfelQ7QJi7ZhvAJxUtu80pildVX6NPLdDaUffOw==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "5.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8", + "System.IO.Compression": "4.3.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Threading.Channels": "5.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Pipelines.Sockets.Unofficial": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "dependencies": { + "System.IO.Pipelines": "5.0.1" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.IO.Compression": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==" + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "5.0.1", + "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Runtime.InteropServices.RuntimeInformation": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==" + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "RLBIxntLaG9pRmmuVDwY1kc8Bvp/FQzSxPU+19VekkScKkWtVP9r8bLhm28ama3usc816UBrmkg3vv3jUea/hw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.ValueTuple": { + "type": "CentralTransitive", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + } + }, + ".NETStandard,Version=v2.0": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Nullable": { + "type": "Direct", + "requested": "[1.3.1, )", + "resolved": "1.3.1", + "contentHash": "Mk4ZVDfAORTjvckQprCSehi1XgOAAlk5ez06Va/acRYEloN9t6d6zpzJRn5MEq7+RnagyFIq9r+kbWzLGd+6QA==" + }, + "StackExchange.Redis": { + "type": "Direct", + "requested": "[2.7.27, )", + "resolved": "2.7.27", + "contentHash": "Uqc2OQHglqj9/FfGQ6RkKFkZfHySfZlfmbCl+hc+u2I/IqunfelQ7QJi7ZhvAJxUtu80pildVX6NPLdDaUffOw==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "5.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8", + "System.Threading.Channels": "5.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Pipelines.Sockets.Unofficial": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "dependencies": { + "System.IO.Pipelines": "5.0.1" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "5.0.1", + "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "RLBIxntLaG9pRmmuVDwY1kc8Bvp/FQzSxPU+19VekkScKkWtVP9r8bLhm28ama3usc816UBrmkg3vv3jUea/hw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + } + }, + ".NETStandard,Version=v2.1": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "StackExchange.Redis": { + "type": "Direct", + "requested": "[2.7.27, )", + "resolved": "2.7.27", + "contentHash": "Uqc2OQHglqj9/FfGQ6RkKFkZfHySfZlfmbCl+hc+u2I/IqunfelQ7QJi7ZhvAJxUtu80pildVX6NPLdDaUffOw==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "5.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8", + "System.Threading.Channels": "5.0.0" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "W8DPQjkMScOMTtJbPwmPyj9c3zYSFGawDW3jwlBOOsnY+EzZFLgNQ/UMkK35JmkNOVPdCyPr2Tw7Vv9N+KA3ZQ==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/HggWBbTwy8TgebGSX5DBZ24ndhzi93sHUBDvP1IxbZD7FDokYzdAr6+vbWGjw2XAfR2EJ1sfKUotpjHnFWPxA==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Pipelines.Sockets.Unofficial": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "dependencies": { + "System.IO.Pipelines": "5.0.1" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "5.0.1", + "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "RLBIxntLaG9pRmmuVDwY1kc8Bvp/FQzSxPU+19VekkScKkWtVP9r8bLhm28ama3usc816UBrmkg3vv3jUea/hw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.SqlServer/DistributedLock.SqlServer.csproj b/src/DistributedLock.SqlServer/DistributedLock.SqlServer.csproj index e8f1bb1..ae83832 100644 --- a/src/DistributedLock.SqlServer/DistributedLock.SqlServer.csproj +++ b/src/DistributedLock.SqlServer/DistributedLock.SqlServer.csproj @@ -1,7 +1,7 @@ - netstandard2.0;netstandard2.1;net461 + netstandard2.0;netstandard2.1;net462 Medallion.Threading.SqlServer True 4 @@ -11,7 +11,7 @@ - 1.0.3 + 1.0.4 1.0.0.0 Michael Adelson Provides a distributed lock implementation based on SQL Server @@ -45,9 +45,9 @@ - - - + + + @@ -58,6 +58,5 @@ - \ No newline at end of file diff --git a/src/DistributedLock.SqlServer/SqlApplicationLock.cs b/src/DistributedLock.SqlServer/SqlApplicationLock.cs index ac7b568..d9037d8 100644 --- a/src/DistributedLock.SqlServer/SqlApplicationLock.cs +++ b/src/DistributedLock.SqlServer/SqlApplicationLock.cs @@ -13,12 +13,12 @@ internal sealed class SqlApplicationLock : IDbSynchronizationStrategy AlreadyHeldExitCode = 103, InvalidUpgradeExitCode = 104; - public static readonly SqlApplicationLock SharedLock = new SqlApplicationLock(Mode.Shared), - UpdateLock = new SqlApplicationLock(Mode.Update), - ExclusiveLock = new SqlApplicationLock(Mode.Exclusive), - UpgradeLock = new SqlApplicationLock(Mode.Exclusive, isUpgrade: true); + public static readonly SqlApplicationLock SharedLock = new(Mode.Shared), + UpdateLock = new(Mode.Update), + ExclusiveLock = new(Mode.Exclusive), + UpgradeLock = new(Mode.Exclusive, isUpgrade: true); - private static readonly object Cookie = new object(); + private static readonly object Cookie = new(); private readonly Mode _mode; private readonly bool _isUpgrade; diff --git a/src/DistributedLock.SqlServer/SqlConnectionOptionsBuilder.cs b/src/DistributedLock.SqlServer/SqlConnectionOptionsBuilder.cs index 9184d39..7bfcf54 100644 --- a/src/DistributedLock.SqlServer/SqlConnectionOptionsBuilder.cs +++ b/src/DistributedLock.SqlServer/SqlConnectionOptionsBuilder.cs @@ -37,8 +37,10 @@ public SqlConnectionOptionsBuilder KeepaliveCadence(TimeSpan keepaliveCadence) /// /// Synchronizing based on a transaction is marginally less expensive than using a connection /// because releasing requires only disposing the underlying . + /// /// The disadvantage is that using this strategy may lead to long-running transactions, which can be - /// problematic for databases using the full recovery model. + /// problematic for databases using the full recovery model. Furthermore, this strategy prevents us from + /// taking advantage of and its performance advantages. /// public SqlConnectionOptionsBuilder UseTransaction(bool useTransaction = true) { @@ -51,7 +53,8 @@ public SqlConnectionOptionsBuilder UseTransaction(bool useTransaction = true) /// a connection is essentially idle. Thus, rather than creating a new connection for each held lock it is /// often possible to multiplex a shared connection so that that connection can hold multiple locks at the same time. /// - /// Multiplexing is on by default. + /// Multiplexing is on by default, unless is set to TRUE in which case multiplexing is disabled + /// because it is not compatible with . /// /// This is implemented in such a way that releasing a lock held on such a connection will never be blocked by an /// Acquire() call that is waiting to acquire a lock on that same connection. For this reason, the multiplexing @@ -83,7 +86,7 @@ internal static (TimeoutValue keepaliveCadence, bool useTransaction, bool useMul var keepaliveCadence = options?._keepaliveCadence ?? TimeSpan.FromMinutes(10); var useTransaction = options?._useTransaction ?? false; - var useMultiplexing = options?._useMultiplexing ?? true; + var useMultiplexing = options?._useMultiplexing ?? !options?._useTransaction ?? true; if (useMultiplexing && useTransaction) { diff --git a/src/DistributedLock.SqlServer/SqlSemaphore.cs b/src/DistributedLock.SqlServer/SqlSemaphore.cs index 6b12ee3..14f8d08 100644 --- a/src/DistributedLock.SqlServer/SqlSemaphore.cs +++ b/src/DistributedLock.SqlServer/SqlSemaphore.cs @@ -278,7 +278,7 @@ private static string HashName(string name) AllTicketsHeldByCurrentSessionCode = SqlApplicationLock.AlreadyHeldExitCode; // when we don't have to deal with cancellation, we can put everything in one big query to save on round trips - private static readonly Lazy AcquireNonCancelableQuery = new Lazy(() => Merge( + private static readonly Lazy AcquireNonCancelableQuery = new(() => Merge( CreateCommonVariableDeclarationsSql(includePreambleLock: true, includeBusyWaitLock: true, includeTryAcquireOnceVariables: true), CreateAcquirePreambleSql(willRetryInSeparateQueryAfterPreamble: null), CreateAcquireSql(cancelable: false), @@ -286,22 +286,22 @@ private static string HashName(string name) )), // for cancellation, we run the preamble first as non-cancellable followed by a cancelable busy wait. This // ensures that we avoid the case where we create a marker table in the preamble and then cancel before returning it - AcquireCancelablePreambleQuery = new Lazy(() => Merge( + AcquireCancelablePreambleQuery = new(() => Merge( CreateCommonVariableDeclarationsSql(includePreambleLock: true, includeBusyWaitLock: false, includeTryAcquireOnceVariables: true), CreateAcquirePreambleSql(willRetryInSeparateQueryAfterPreamble: true), CreateCodaSql(includePreambleLockRelease: true, includeBusyWaitLockRelease: false) )), - AcquireCancelableQuery = new Lazy(() => Merge( + AcquireCancelableQuery = new(() => Merge( CreateCommonVariableDeclarationsSql(includePreambleLock: false, includeBusyWaitLock: true, includeTryAcquireOnceVariables: true), CreateAcquireSql(cancelable: true), CreateCodaSql(includePreambleLockRelease: false, includeBusyWaitLockRelease: true) )), - CancellationCleanupQuery = new Lazy(() => Merge( + CancellationCleanupQuery = new(() => Merge( CreateCommonVariableDeclarationsSql(includePreambleLock: false, includeBusyWaitLock: true, includeTryAcquireOnceVariables: false), CreateCancellationCleanupSql(), CreateCodaSql(includePreambleLockRelease: false, includeBusyWaitLockRelease: true) )), - ReleaseQuery = new Lazy(() => Merge( + ReleaseQuery = new(() => Merge( CreateCommonVariableDeclarationsSql(includePreambleLock: false, includeBusyWaitLock: false, includeTryAcquireOnceVariables: false), CreateReleaseSql() )); diff --git a/src/DistributedLock.SqlServer/packages.lock.json b/src/DistributedLock.SqlServer/packages.lock.json new file mode 100644 index 0000000..c97f9b9 --- /dev/null +++ b/src/DistributedLock.SqlServer/packages.lock.json @@ -0,0 +1,1242 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.Data.SqlClient": { + "type": "Direct", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "System.Buffers": "4.5.1", + "System.Configuration.ConfigurationManager": "6.0.1", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Text.Encodings.Web": "6.0.0" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.35.0", + "contentHash": "hENcx03Jyuqv05F4RBEPbxz29UrM3Nbhnr6Wl6NQpoU9BCIbL3XLentrxDCTrH54NLS11Exxi/o8MYgT/cnKFA==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Net.Http": "4.3.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.10.3", + "contentHash": "l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==", + "dependencies": { + "Azure.Core": "1.35.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.Identity.Client.Extensions.Msal": "4.56.0", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.7.0", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Data.SqlClient.SNI": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "0p2KMVc8WSC5JWgO+OdhYJiRM41dp6w2Dsd9JfEiHLPc6nyxBQgSrx9TYlbC8fRT2RK+HyWzDlv9ofFtxMOwQg==" + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.22.0" + } + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==", + "dependencies": { + "Microsoft.Identity.Client": "4.56.0", + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "6.35.0", + "System.IdentityModel.Tokens.Jwt": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "jXw9MlUu/kRfEU0WyTptAVueupqIeE3/rl0EZDMlf8pcvJnitQ8HeVEp69rZdaStXwTV72boi/Bhw8lOeO+U2w==", + "dependencies": { + "System.Security.Permissions": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "KiLYDu2k2J82Q9BJpWiuQqCkFjRBWVq4jDzKKWawVi9KWzyD0XG3cmfX0vqTQlL14Wi9EufJrbL0+KCLTbqWiQ==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Net.Http": { + "type": "Transitive", + "resolved": "4.3.4", + "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", + "dependencies": { + "System.Security.Cryptography.X509Certificates": "4.3.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Runtime.InteropServices.RuntimeInformation": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Cryptography.Algorithms": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==", + "dependencies": { + "System.Security.Cryptography.Primitives": "4.3.0" + } + }, + "System.Security.Cryptography.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==" + }, + "System.Security.Cryptography.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==" + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "ehYW0m9ptxpGWvE4zgqongBVWpSDU/JCFD4K7krxkQwSz/sFQjEXCUqpvencjy6DYDbn7Ig09R8GFffu8TtneQ==" + }, + "System.Security.Cryptography.X509Certificates": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==", + "dependencies": { + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0" + } + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "TcMd95wcrubm9nHvJEQs70rC0H/8omiSGGpU4FQ/ZA1URIqD4pjmFJh2Mfv1yH1eHgJDWTi2hMDXwTET+zOOyg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.1", + "System.Text.Encodings.Web": "4.7.1", + "System.Threading.Tasks.Extensions": "4.5.4", + "System.ValueTuple": "4.5.0" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.ValueTuple": { + "type": "CentralTransitive", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + } + }, + ".NETStandard,Version=v2.0": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.Data.SqlClient": { + "type": "Direct", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI.runtime": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "Microsoft.SqlServer.Server": "1.0.0", + "Microsoft.Win32.Registry": "5.0.0", + "System.Buffers": "4.5.1", + "System.Configuration.ConfigurationManager": "6.0.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Runtime.Caching": "6.0.0", + "System.Runtime.Loader": "4.3.0", + "System.Security.Cryptography.Cng": "5.0.0", + "System.Security.Principal.Windows": "5.0.0", + "System.Text.Encoding.CodePages": "6.0.0", + "System.Text.Encodings.Web": "6.0.0" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.35.0", + "contentHash": "hENcx03Jyuqv05F4RBEPbxz29UrM3Nbhnr6Wl6NQpoU9BCIbL3XLentrxDCTrH54NLS11Exxi/o8MYgT/cnKFA==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.10.3", + "contentHash": "l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==", + "dependencies": { + "Azure.Core": "1.35.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.Identity.Client.Extensions.Msal": "4.56.0", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.7.0", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CSharp": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "kaj6Wb4qoMuH3HySFJhxwQfe8R/sJsNJnANrvv8WdFPMoNbKY5htfNscv+LHCu5ipz+49m2e+WQXpLXr9XYemQ==" + }, + "Microsoft.Data.SqlClient.SNI.runtime": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "po1jhvFd+8pbfvJR/puh+fkHi0GRanAdvayh/0e47yaM6CXWZ6opUjCMFuYlAnD2LcbyvQE7fPJKvogmaUcN+w==" + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.22.0" + } + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==", + "dependencies": { + "Microsoft.Identity.Client": "4.56.0", + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "6.35.0", + "System.IdentityModel.Tokens.Jwt": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==", + "dependencies": { + "Microsoft.CSharp": "4.5.0", + "Microsoft.IdentityModel.Logging": "6.35.0", + "System.Security.Cryptography.Cng": "4.5.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Microsoft.SqlServer.Server": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "N4KeF3cpcm1PUHym1RmakkzfkEv3GRMyofVv40uXsQhCQeglr2OHNcUk2WOG51AKpGO8ynGpo9M/kFXSzghwug==" + }, + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "jXw9MlUu/kRfEU0WyTptAVueupqIeE3/rl0EZDMlf8pcvJnitQ8HeVEp69rZdaStXwTV72boi/Bhw8lOeO+U2w==", + "dependencies": { + "System.Security.Cryptography.ProtectedData": "6.0.0", + "System.Security.Permissions": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "KiLYDu2k2J82Q9BJpWiuQqCkFjRBWVq4jDzKKWawVi9KWzyD0XG3cmfX0vqTQlL14Wi9EufJrbL0+KCLTbqWiQ==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "System.IO": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Reflection": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "System.Runtime.Caching": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "E0e03kUp5X2k+UAoVl6efmI7uU7JRBWi5EIdlQ7cr0NpBGjHG4fWII35PgsBY9T4fJQ8E4QPsL0rKksU9gcL5A==", + "dependencies": { + "System.Configuration.ConfigurationManager": "6.0.0" + } + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Runtime.Loader": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "DHMaRn8D8YCK2GG2pw+UzNxn/OHVfaWx7OTLBD/hPegHZZgcZh3H6seWegrC4BYwsfuGrywIuT+MQs+rPqRLTQ==", + "dependencies": { + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Cryptography.Cng": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "jIMXsKn94T9JY7PvPq/tMfqa6GAaHpElRDpmG+SuL+D3+sTw2M8VhnibKnN8Tq+4JqbPJ/f+BwtLeDMEnzAvRg==" + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ==", + "dependencies": { + "System.Memory": "4.5.4" + } + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "TcMd95wcrubm9nHvJEQs70rC0H/8omiSGGpU4FQ/ZA1URIqD4pjmFJh2Mfv1yH1eHgJDWTi2hMDXwTET+zOOyg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.1", + "System.Text.Encodings.Web": "4.7.1", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + } + }, + ".NETStandard,Version=v2.1": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.Data.SqlClient": { + "type": "Direct", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI.runtime": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "Microsoft.SqlServer.Server": "1.0.0", + "Microsoft.Win32.Registry": "5.0.0", + "System.Configuration.ConfigurationManager": "6.0.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Runtime.Caching": "6.0.0", + "System.Runtime.Loader": "4.3.0", + "System.Security.Cryptography.Cng": "5.0.0", + "System.Security.Principal.Windows": "5.0.0", + "System.Text.Encoding.CodePages": "6.0.0", + "System.Text.Encodings.Web": "6.0.0" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.35.0", + "contentHash": "hENcx03Jyuqv05F4RBEPbxz29UrM3Nbhnr6Wl6NQpoU9BCIbL3XLentrxDCTrH54NLS11Exxi/o8MYgT/cnKFA==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.10.3", + "contentHash": "l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==", + "dependencies": { + "Azure.Core": "1.35.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.Identity.Client.Extensions.Msal": "4.56.0", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.7.0", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "yuvf07qFWFqtK3P/MRkEKLhn5r2UbSpVueRziSqj0yJQIKFwG1pq9mOayK3zE5qZCTs0CbrwL9M6R8VwqyGy2w==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CSharp": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "kaj6Wb4qoMuH3HySFJhxwQfe8R/sJsNJnANrvv8WdFPMoNbKY5htfNscv+LHCu5ipz+49m2e+WQXpLXr9XYemQ==" + }, + "Microsoft.Data.SqlClient.SNI.runtime": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "po1jhvFd+8pbfvJR/puh+fkHi0GRanAdvayh/0e47yaM6CXWZ6opUjCMFuYlAnD2LcbyvQE7fPJKvogmaUcN+w==" + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.22.0" + } + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==", + "dependencies": { + "Microsoft.Identity.Client": "4.56.0", + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "6.35.0", + "System.IdentityModel.Tokens.Jwt": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==", + "dependencies": { + "Microsoft.CSharp": "4.5.0", + "Microsoft.IdentityModel.Logging": "6.35.0", + "System.Security.Cryptography.Cng": "4.5.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Microsoft.SqlServer.Server": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "N4KeF3cpcm1PUHym1RmakkzfkEv3GRMyofVv40uXsQhCQeglr2OHNcUk2WOG51AKpGO8ynGpo9M/kFXSzghwug==" + }, + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "jXw9MlUu/kRfEU0WyTptAVueupqIeE3/rl0EZDMlf8pcvJnitQ8HeVEp69rZdaStXwTV72boi/Bhw8lOeO+U2w==", + "dependencies": { + "System.Security.Cryptography.ProtectedData": "6.0.0", + "System.Security.Permissions": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "KiLYDu2k2J82Q9BJpWiuQqCkFjRBWVq4jDzKKWawVi9KWzyD0XG3cmfX0vqTQlL14Wi9EufJrbL0+KCLTbqWiQ==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "System.IO": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Reflection": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "System.Runtime.Caching": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "E0e03kUp5X2k+UAoVl6efmI7uU7JRBWi5EIdlQ7cr0NpBGjHG4fWII35PgsBY9T4fJQ8E4QPsL0rKksU9gcL5A==", + "dependencies": { + "System.Configuration.ConfigurationManager": "6.0.0" + } + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Runtime.Loader": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "DHMaRn8D8YCK2GG2pw+UzNxn/OHVfaWx7OTLBD/hPegHZZgcZh3H6seWegrC4BYwsfuGrywIuT+MQs+rPqRLTQ==", + "dependencies": { + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Cryptography.Cng": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "jIMXsKn94T9JY7PvPq/tMfqa6GAaHpElRDpmG+SuL+D3+sTw2M8VhnibKnN8Tq+4JqbPJ/f+BwtLeDMEnzAvRg==" + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ==", + "dependencies": { + "System.Memory": "4.5.4" + } + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Vg8eB5Tawm1IFqj4TVK1czJX89rhFxJo9ELqc/Eiq0eXy13RK00eubyU6TJE6y+GQXjyV5gSfiewDUZjQgSE0w==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "TcMd95wcrubm9nHvJEQs70rC0H/8omiSGGpU4FQ/ZA1URIqD4pjmFJh2Mfv1yH1eHgJDWTi2hMDXwTET+zOOyg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.7.1", + "System.Text.Encodings.Web": "4.7.1", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.Tests/AbstractTestCases/Data/ConnectionStringStrategyTestCases.cs b/src/DistributedLock.Tests/AbstractTestCases/Data/ConnectionStringStrategyTestCases.cs index e9bbf37..9807af4 100644 --- a/src/DistributedLock.Tests/AbstractTestCases/Data/ConnectionStringStrategyTestCases.cs +++ b/src/DistributedLock.Tests/AbstractTestCases/Data/ConnectionStringStrategyTestCases.cs @@ -69,7 +69,7 @@ public void TestKeepaliveProtectsFromIdleSessionKiller() var handle = @lock.Acquire(); using var idleSessionKiller = new IdleSessionKiller(this._lockProvider.Strategy.Db, applicationName, idleTimeout: TimeSpan.FromSeconds(.5)); Thread.Sleep(TimeSpan.FromSeconds(2)); - Assert.DoesNotThrow(() => handle.Dispose()); + Assert.DoesNotThrow(handle.Dispose); } /// @@ -110,7 +110,7 @@ public async Task TestAccessingHandleLostTokenWhileKeepaliveActiveDoesNotBlock() handle.HandleLostToken.Register(() => { }); } }); - Assert.IsTrue(await accessHandleLostTokenTask.WaitAsync(TimeSpan.FromSeconds(5))); + Assert.IsTrue(await accessHandleLostTokenTask.TryWaitAsync(TimeSpan.FromSeconds(5))); // do this only on success; on failure we're likely deadlocked and dispose will hang await handle.DisposeAsync(); diff --git a/src/DistributedLock.Tests/AbstractTestCases/Data/DbSemaphoreTestCases.cs b/src/DistributedLock.Tests/AbstractTestCases/Data/DbSemaphoreTestCases.cs index 17456fc..91240ac 100644 --- a/src/DistributedLock.Tests/AbstractTestCases/Data/DbSemaphoreTestCases.cs +++ b/src/DistributedLock.Tests/AbstractTestCases/Data/DbSemaphoreTestCases.cs @@ -24,7 +24,7 @@ public void TestSelfDeadlockThrowsOnInfiniteWait() semaphore.Acquire(); semaphore.Acquire(); var ex = Assert.Catch(() => semaphore.Acquire()); - ex.Message.Contains("Deadlock").ShouldEqual(true, ex.Message); + ex!.Message.Contains("Deadlock").ShouldEqual(true, ex.Message); } [Test] diff --git a/src/DistributedLock.Tests/AbstractTestCases/Data/ExternalConnectionOrTransactionStrategyTestCases.cs b/src/DistributedLock.Tests/AbstractTestCases/Data/ExternalConnectionOrTransactionStrategyTestCases.cs index 636d8f8..538c04b 100644 --- a/src/DistributedLock.Tests/AbstractTestCases/Data/ExternalConnectionOrTransactionStrategyTestCases.cs +++ b/src/DistributedLock.Tests/AbstractTestCases/Data/ExternalConnectionOrTransactionStrategyTestCases.cs @@ -25,7 +25,7 @@ public void TestDeadlockDetection() const string LockName1 = nameof(TestDeadlockDetection) + "_1", LockName2 = nameof(TestDeadlockDetection) + "_2"; - Task RunDeadlock(bool isFirst) + Task RunDeadlockAsync(bool isFirst) { this._lockProvider.Strategy.StartAmbient(); var lock1 = this._lockProvider.CreateLock(isFirst ? LockName1 : LockName2); @@ -40,7 +40,7 @@ Task RunDeadlock(bool isFirst) }); } - var tasks = new[] { RunDeadlock(isFirst: true), RunDeadlock(isFirst: false) }; + var tasks = new[] { RunDeadlockAsync(isFirst: true), RunDeadlockAsync(isFirst: false) }; Task.WhenAll(tasks).ContinueWith(_ => { }).Wait(TimeSpan.FromSeconds(15)).ShouldEqual(true, this.GetType().Name); @@ -95,7 +95,7 @@ public void TestStateChangeHandlerIsNotLeaked() .Where(f => f.FieldType == typeof(StateChangeEventHandler)) .SingleOrDefault() ) - .First(f => f != null) + .First(f => f != null)! .GetValue(connection); } } diff --git a/src/DistributedLock.Tests/AbstractTestCases/Data/ExternalTransactionStrategyTestCases.cs b/src/DistributedLock.Tests/AbstractTestCases/Data/ExternalTransactionStrategyTestCases.cs index c5137c5..b596f1e 100644 --- a/src/DistributedLock.Tests/AbstractTestCases/Data/ExternalTransactionStrategyTestCases.cs +++ b/src/DistributedLock.Tests/AbstractTestCases/Data/ExternalTransactionStrategyTestCases.cs @@ -53,7 +53,7 @@ private class SpecificConnectionStrategy : TestingDbSynchronizationStrategy public ExternalTransactionStrategyTestCases? Test { get; set; } public override TestingDbConnectionOptions GetConnectionOptions() => - new TestingDbConnectionOptions { Connection = this.Test!._lockProvider.Strategy.AmbientTransaction!.Connection }; + new() { Connection = this.Test!._lockProvider.Strategy.AmbientTransaction!.Connection }; } public void TestCloseTransactionLockOnClosedConnectionOrTransaction([Values] bool closeConnection) @@ -74,7 +74,7 @@ public void TestCloseTransactionLockOnClosedConnectionOrTransaction([Values] boo if (closeConnection) { - this._lockProvider.Strategy.AmbientTransaction!.Connection.Dispose(); + this._lockProvider.Strategy.AmbientTransaction!.Connection!.Dispose(); } else { diff --git a/src/DistributedLock.Tests/AbstractTestCases/Data/OwnedConnectionStrategyTestCases.cs b/src/DistributedLock.Tests/AbstractTestCases/Data/OwnedConnectionStrategyTestCases.cs index 67db6cb..1e25fb3 100644 --- a/src/DistributedLock.Tests/AbstractTestCases/Data/OwnedConnectionStrategyTestCases.cs +++ b/src/DistributedLock.Tests/AbstractTestCases/Data/OwnedConnectionStrategyTestCases.cs @@ -53,6 +53,6 @@ public void TestIdleSessionKiller() } } - Assert.Catch(() => handle.Dispose()); + Assert.Catch(handle.Dispose); } } diff --git a/src/DistributedLock.Tests/AbstractTestCases/DistributedLockCoreTestCases.cs b/src/DistributedLock.Tests/AbstractTestCases/DistributedLockCoreTestCases.cs index 0417074..ba0d6d7 100644 --- a/src/DistributedLock.Tests/AbstractTestCases/DistributedLockCoreTestCases.cs +++ b/src/DistributedLock.Tests/AbstractTestCases/DistributedLockCoreTestCases.cs @@ -12,7 +12,7 @@ public abstract class DistributedLockCoreTestCases where TStrategy : TestingSynchronizationStrategy, new() { private TLockProvider _lockProvider = default!; - private readonly List _cleanupActions = new List(); + private readonly List _cleanupActions = []; [SetUp] public void SetUp() => this._lockProvider = new TLockProvider(); @@ -99,8 +99,8 @@ public void TestDisposeHandleIsIdempotent() Assert.IsNotNull(handle); handle.Dispose(); var handle2 = @lock.Acquire(TimeSpan.FromSeconds(30)); - Assert.DoesNotThrow(() => handle.Dispose()); - Assert.DoesNotThrow(() => handle2.Dispose()); + Assert.DoesNotThrow(handle.Dispose); + Assert.DoesNotThrow(handle2.Dispose); } [Test] diff --git a/src/DistributedLock.Tests/AbstractTestCases/DistributedReaderWriterLockCoreTestCases.cs b/src/DistributedLock.Tests/AbstractTestCases/DistributedReaderWriterLockCoreTestCases.cs index 08f795d..22e3b86 100644 --- a/src/DistributedLock.Tests/AbstractTestCases/DistributedReaderWriterLockCoreTestCases.cs +++ b/src/DistributedLock.Tests/AbstractTestCases/DistributedReaderWriterLockCoreTestCases.cs @@ -53,7 +53,7 @@ IDistributedReaderWriterLock Lock() => await using var readerHandle = await Lock().AcquireReadLockAsync(); var writerHandleTask = Task.Run(() => Lock().AcquireWriteLockAsync().AsTask()); - Assert.IsFalse(await writerHandleTask.WaitAsync(TimeSpan.FromSeconds(0.2))); + Assert.IsFalse(await writerHandleTask.TryWaitAsync(TimeSpan.FromSeconds(0.2))); // trying to take a read lock here fails because there is a writer waiting await using var readerHandle2 = await Lock().TryAcquireReadLockAsync(); @@ -61,7 +61,7 @@ IDistributedReaderWriterLock Lock() => await readerHandle.DisposeAsync(); - Assert.IsTrue(await writerHandleTask.WaitAsync(TimeSpan.FromSeconds(5))); + Assert.IsTrue(await writerHandleTask.TryWaitAsync(TimeSpan.FromSeconds(5))); await writerHandleTask.Result.DisposeAsync(); } diff --git a/src/DistributedLock.Tests/AbstractTestCases/Redis/RedisExtensionTestCases.cs b/src/DistributedLock.Tests/AbstractTestCases/Redis/RedisExtensionTestCases.cs index 8d0f216..eae0659 100644 --- a/src/DistributedLock.Tests/AbstractTestCases/Redis/RedisExtensionTestCases.cs +++ b/src/DistributedLock.Tests/AbstractTestCases/Redis/RedisExtensionTestCases.cs @@ -25,10 +25,10 @@ public async Task TestCanExtendLock() var secondHandleTask = @lock.AcquireAsync().AsTask(); _ = secondHandleTask.ContinueWith(t => t.Result.Dispose()); // ensure cleanup - Assert.IsFalse(await secondHandleTask.WaitAsync(TimeSpan.FromSeconds(2))); + Assert.IsFalse(await secondHandleTask.TryWaitAsync(TimeSpan.FromSeconds(2))); await handle.DisposeAsync(); - Assert.IsTrue(await secondHandleTask.WaitAsync(TimeSpan.FromSeconds(5))); + Assert.IsTrue(await secondHandleTask.TryWaitAsync(TimeSpan.FromSeconds(5))); } } diff --git a/src/DistributedLock.Tests/AbstractTestCases/Redis/RedisSynchronizationCoreTestCases.cs b/src/DistributedLock.Tests/AbstractTestCases/Redis/RedisSynchronizationCoreTestCases.cs index 966ce4d..16b4c90 100644 --- a/src/DistributedLock.Tests/AbstractTestCases/Redis/RedisSynchronizationCoreTestCases.cs +++ b/src/DistributedLock.Tests/AbstractTestCases/Redis/RedisSynchronizationCoreTestCases.cs @@ -66,7 +66,7 @@ public void TestMajorityFaultingDatabasesCauseReleaseToThrow() using var handle = @lock.Acquire(); new List { 1, 2, 4 }.ForEach(i => MockDatabase(databases[i], () => throw new DataMisalignedException())); - var aggregateException = Assert.Throws(() => handle.Dispose()); + var aggregateException = Assert.Throws(() => handle.Dispose())!; Assert.IsInstanceOf(aggregateException.InnerException); } @@ -167,5 +167,7 @@ private static void MockDatabase(Mock mockDatabase, Func return .Returns(() => (bool)RedisResult.Create(returns())); mockDatabase.Setup(d => d.SortedSetRemoveAsync(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(() => Task.Run(() => (bool)RedisResult.Create(returns()))); + mockDatabase.Setup(d => d.IsConnected(It.IsAny(), It.IsAny())) + .Returns(true); } } diff --git a/src/DistributedLock.Tests/AbstractTestCases/ZooKeeper/ZooKeeperSynchronizationCoreTestCases.cs b/src/DistributedLock.Tests/AbstractTestCases/ZooKeeper/ZooKeeperSynchronizationCoreTestCases.cs index 16bbde6..6369d60 100644 --- a/src/DistributedLock.Tests/AbstractTestCases/ZooKeeper/ZooKeeperSynchronizationCoreTestCases.cs +++ b/src/DistributedLock.Tests/AbstractTestCases/ZooKeeper/ZooKeeperSynchronizationCoreTestCases.cs @@ -39,7 +39,7 @@ public async Task TestDoesNotAttemptToCreateOrDeleteExistingNode() var @lock = this._provider.CreateLockWithExactName(path.ToString()); Assert.That( - Assert.ThrowsAsync(() => @lock.TryAcquireAsync().AsTask()).Message, + Assert.ThrowsAsync(() => @lock.TryAcquireAsync().AsTask())!.Message, Does.Contain("does not exist") ); diff --git a/src/DistributedLock.Tests/DistributedLock.Tests.csproj b/src/DistributedLock.Tests/DistributedLock.Tests.csproj index e16c909..c1a9174 100644 --- a/src/DistributedLock.Tests/DistributedLock.Tests.csproj +++ b/src/DistributedLock.Tests/DistributedLock.Tests.csproj @@ -2,8 +2,8 @@ - netcoreapp3.1 - net471;netcoreapp3.1 + net8.0 + net472;net8.0 Latest enable enable @@ -12,15 +12,17 @@ ..\DistributedLock.snk true 1591 + + false - - - - - - + + + + + + diff --git a/src/DistributedLock.Tests/Infrastructure/Azure/AzureSetUpFixture.cs b/src/DistributedLock.Tests/Infrastructure/Azure/AzureSetUpFixture.cs index 11228b1..9e410d4 100644 --- a/src/DistributedLock.Tests/Infrastructure/Azure/AzureSetUpFixture.cs +++ b/src/DistributedLock.Tests/Infrastructure/Azure/AzureSetUpFixture.cs @@ -8,7 +8,8 @@ namespace Medallion.Threading.Tests.Azure; [SetUpFixture] public class AzureSetUpFixture { - private const string EmulatorProcessName = "AzureStorageEmulator"; + // https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite?tabs=visual-studio%2Cblob-storage + private const string EmulatorProcessName = "azurite"; private bool _startedEmulator; @@ -23,15 +24,23 @@ public void OneTimeSetUp() } else { - var emulatorExePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86), "Microsoft SDKs", "Azure", "Storage Emulator", $"{EmulatorProcessName}.exe"); - if (!File.Exists(emulatorExePath)) + var emulatorExePaths = Directory.GetFiles(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "Microsoft Visual Studio"), $"{EmulatorProcessName}.exe", SearchOption.AllDirectories) + .OrderByDescending(File.GetLastWriteTimeUtc) + .ToArray(); + if (!emulatorExePaths.Any()) { - throw new FileNotFoundException($"Could not locate the {EmulatorProcessName} at {emulatorExePath}. This is required to run Azure tests. See https://docs.microsoft.com/en-us/azure/storage/common/storage-use-emulator"); + throw new FileNotFoundException($"Could not locate {EmulatorProcessName}. This is required to run Azure tests. See https://learn.microsoft.com/en-us/azure/storage/common/storage-use-azurite"); } // Note: we used to hang on to this command to kill it later; we no longer do that because this process seems to naturally exit // by the end of the test and instead the emulator is running in another process. Therefore, we do a name-based lookup in teardown instead. - var command = Command.Run(emulatorExePath, new[] { "start" }, o => o.StartInfo(i => i.RedirectStandardInput = false)) + var command = Command.Run( + emulatorExePaths[0], + // After updating to Azure.Storage.Blobs 12.19.1 I started getting an error saying that I had to update Azurite or pass this flag. + // AFAIK the only way to update Azurite is to update VS, which did not fix the issue. Therefore, I am passing this flag instead. + ["start", "--skipApiVersionCheck"], + o => o.StartInfo(i => i.RedirectStandardInput = false) + .WorkingDirectory(Path.GetDirectoryName(this.GetType().Assembly.Location)!)) .RedirectTo(Console.Out) .RedirectStandardErrorTo(Console.Error); Console.WriteLine($"Launched {EmulatorProcessName}"); diff --git a/src/DistributedLock.Tests/Infrastructure/Azure/TestingAzureBlobLeaseDistributedLockProvider.cs b/src/DistributedLock.Tests/Infrastructure/Azure/TestingAzureBlobLeaseDistributedLockProvider.cs index 8f92664..6dfc26f 100644 --- a/src/DistributedLock.Tests/Infrastructure/Azure/TestingAzureBlobLeaseDistributedLockProvider.cs +++ b/src/DistributedLock.Tests/Infrastructure/Azure/TestingAzureBlobLeaseDistributedLockProvider.cs @@ -5,7 +5,7 @@ namespace Medallion.Threading.Tests.Azure; public sealed class TestingAzureBlobLeaseDistributedLockProvider : TestingLockProvider { - private readonly HashSet _createdBlobs = new HashSet(); + private readonly HashSet _createdBlobs = []; public override IDistributedLock CreateLockWithExactName(string name) { @@ -16,7 +16,8 @@ public override IDistributedLock CreateLockWithExactName(string name) { if (this._createdBlobs.Add(client.Uri)) { - client.Upload(Stream.Null); + // Azurite blobs persist across runs, so we need overwrite: true + client.Upload(Stream.Null, overwrite: true); } } } diff --git a/src/DistributedLock.Tests/Infrastructure/Azure/TestingAzureBlobLeaseSynchronizationStrategy.cs b/src/DistributedLock.Tests/Infrastructure/Azure/TestingAzureBlobLeaseSynchronizationStrategy.cs index dd9d8e5..eaedd1a 100644 --- a/src/DistributedLock.Tests/Infrastructure/Azure/TestingAzureBlobLeaseSynchronizationStrategy.cs +++ b/src/DistributedLock.Tests/Infrastructure/Azure/TestingAzureBlobLeaseSynchronizationStrategy.cs @@ -10,7 +10,7 @@ namespace Medallion.Threading.Tests.Azure; public sealed class TestingAzureBlobLeaseSynchronizationStrategy : TestingSynchronizationStrategy { - private readonly DisposableCollection _disposables = new DisposableCollection(); + private readonly DisposableCollection _disposables = new(); private static readonly Action DefaultTestingOptions = o => // for test speed diff --git a/src/DistributedLock.Tests/Infrastructure/Data/TestingDbSynchronizationStrategy.cs b/src/DistributedLock.Tests/Infrastructure/Data/TestingDbSynchronizationStrategy.cs index 3ad9819..91e8bc0 100644 --- a/src/DistributedLock.Tests/Infrastructure/Data/TestingDbSynchronizationStrategy.cs +++ b/src/DistributedLock.Tests/Infrastructure/Data/TestingDbSynchronizationStrategy.cs @@ -50,7 +50,7 @@ public abstract class TestingConnectionStringSynchronizationStrategy : Test public TimeSpan? KeepaliveCadence { get; set; } public sealed override TestingDbConnectionOptions GetConnectionOptions() => - new TestingDbConnectionOptions + new() { ConnectionString = this.Db.ConnectionString, ConnectionStringUseMultiplexing = this.UseMultiplexingNotTransaction == true, @@ -136,7 +136,7 @@ public sealed override void PerformAdditionalCleanupForHandleAbandonment() public sealed class TestingExternalConnectionSynchronizationStrategy : TestingExternalConnectionOrTransactionSynchronizationStrategy where TDb : TestingDb, new() { - private readonly DisposableCollection _disposables = new DisposableCollection(); + private readonly DisposableCollection _disposables = new(); private DbConnection? _ambientConnection; public override DbConnection? AmbientConnection => this._ambientConnection; @@ -177,7 +177,7 @@ public override void Dispose() public sealed class TestingExternalTransactionSynchronizationStrategy : TestingExternalConnectionOrTransactionSynchronizationStrategy where TDb : TestingDb, new() { - private readonly DisposableCollection _disposables = new DisposableCollection(); + private readonly DisposableCollection _disposables = new(); public DbTransaction? AmbientTransaction { get; private set; } public override DbConnection? AmbientConnection => this.AmbientTransaction?.Connection; diff --git a/src/DistributedLock.Tests/Infrastructure/MySql/TestingMySqlDb.cs b/src/DistributedLock.Tests/Infrastructure/MySql/TestingMySqlDb.cs index be7f094..827e293 100644 --- a/src/DistributedLock.Tests/Infrastructure/MySql/TestingMySqlDb.cs +++ b/src/DistributedLock.Tests/Infrastructure/MySql/TestingMySqlDb.cs @@ -11,8 +11,8 @@ public class TestingMySqlDb : TestingPrimaryClientDb private readonly string _defaultConnectionString; private readonly MySqlConnectionStringBuilder _connectionStringBuilder; - public TestingMySqlDb() : - this(MySqlCredentials.GetConnectionString(TestContext.CurrentContext.TestDirectory)) + public TestingMySqlDb() + : this(MySqlCredentials.GetConnectionString(TestContext.CurrentContext.TestDirectory)) { } diff --git a/src/DistributedLock.Tests/Infrastructure/Oracle/TestingOracleDb.cs b/src/DistributedLock.Tests/Infrastructure/Oracle/TestingOracleDb.cs index 2d390ba..0b5c773 100644 --- a/src/DistributedLock.Tests/Infrastructure/Oracle/TestingOracleDb.cs +++ b/src/DistributedLock.Tests/Infrastructure/Oracle/TestingOracleDb.cs @@ -12,7 +12,7 @@ public sealed class TestingOracleDb : TestingPrimaryClientDb { internal static readonly string DefaultConnectionString = OracleCredentials.GetConnectionString(TestContext.CurrentContext.TestDirectory); - private readonly OracleConnectionStringBuilder _connectionStringBuilder = new OracleConnectionStringBuilder(DefaultConnectionString); + private readonly OracleConnectionStringBuilder _connectionStringBuilder = new(DefaultConnectionString); public override DbConnectionStringBuilder ConnectionStringBuilder => this._connectionStringBuilder; @@ -51,10 +51,10 @@ public override IsolationLevel GetIsolationLevel(DbConnection connection) public override void PrepareForHighContention(ref int maxConcurrentAcquires) { - // The free Oracle Autonomous database has a fixed max session limit of 20. When concurrency approaches that, parellel + // Oracle XE has a default max session limit of 20. When concurrency approaches that, parellel // execution slows down greatly because often releases become queued behind competing aquires. When concurrency surpasses // that level we risk total deadlock where all active sessions are in use by acquires and as such no release can ever get - // through. + // through. It's possible that we could configure a higher limit but I'm not sure that's necessary. maxConcurrentAcquires = Math.Min(maxConcurrentAcquires, 15); } diff --git a/src/DistributedLock.Tests/Infrastructure/Oracle/TestingOracleProviders.cs b/src/DistributedLock.Tests/Infrastructure/Oracle/TestingOracleProviders.cs index 16a990a..90729c4 100644 --- a/src/DistributedLock.Tests/Infrastructure/Oracle/TestingOracleProviders.cs +++ b/src/DistributedLock.Tests/Infrastructure/Oracle/TestingOracleProviders.cs @@ -11,7 +11,7 @@ public override IDistributedLock CreateLockWithExactName(string name) => .Create( (connectionString, options) => new OracleDistributedLock(name, connectionString, options: ToOracleOptions(options)), connection => new OracleDistributedLock(name, connection), - transaction => new OracleDistributedLock(name, transaction.Connection) + transaction => new OracleDistributedLock(name, transaction.Connection!) ); public override string GetSafeName(string name) => new OracleDistributedLock(name, TestingOracleDb.DefaultConnectionString).Name; @@ -32,7 +32,7 @@ public override IDistributedUpgradeableReaderWriterLock CreateUpgradeableReaderW (connectionString, options) => new OracleDistributedReaderWriterLock(name, connectionString, TestingOracleDistributedLockProvider.ToOracleOptions(options), exactName: true), connection => new OracleDistributedReaderWriterLock(name, connection, exactName: true), - transaction => new OracleDistributedReaderWriterLock(name, transaction.Connection, exactName: true)); + transaction => new OracleDistributedReaderWriterLock(name, transaction.Connection!, exactName: true)); public override string GetSafeName(string name) => new OracleDistributedReaderWriterLock(name, TestingOracleDb.DefaultConnectionString).Name; } diff --git a/src/DistributedLock.Tests/Infrastructure/Postgres/TestingPostgresDb.cs b/src/DistributedLock.Tests/Infrastructure/Postgres/TestingPostgresDb.cs index 280db91..46a137a 100644 --- a/src/DistributedLock.Tests/Infrastructure/Postgres/TestingPostgresDb.cs +++ b/src/DistributedLock.Tests/Infrastructure/Postgres/TestingPostgresDb.cs @@ -12,7 +12,7 @@ public sealed class TestingPostgresDb : TestingPrimaryClientDb { internal static readonly string DefaultConnectionString = PostgresCredentials.GetConnectionString(TestContext.CurrentContext.TestDirectory); - private readonly NpgsqlConnectionStringBuilder _connectionStringBuilder = new NpgsqlConnectionStringBuilder(DefaultConnectionString); + private readonly NpgsqlConnectionStringBuilder _connectionStringBuilder = new(DefaultConnectionString); public override DbConnectionStringBuilder ConnectionStringBuilder => this._connectionStringBuilder; @@ -43,7 +43,7 @@ public override IsolationLevel GetIsolationLevel(DbConnection connection) using var command = connection.CreateCommand(); // values based on https://www.postgresql.org/docs/12/transaction-iso.html command.CommandText = "SELECT REPLACE(current_setting('transaction_isolation'), ' ', '')"; - return (IsolationLevel)Enum.Parse(typeof(IsolationLevel), (string)command.ExecuteScalar(), ignoreCase: true); + return (IsolationLevel)Enum.Parse(typeof(IsolationLevel), (string)command.ExecuteScalar()!, ignoreCase: true); } public override DbConnection CreateConnection() => new NpgsqlConnection(this.ConnectionStringBuilder.ConnectionString); @@ -63,7 +63,7 @@ @idleSince IS NULL OR (state = 'idle' AND state_change < @idleSince) )"; command.Parameters.AddWithValue("applicationName", applicationName); - command.Parameters.Add(new NpgsqlParameter("idleSince", idleSince ?? DBNull.Value.As()) { NpgsqlDbType = NpgsqlDbType.TimestampTz }); + command.Parameters.Add(new NpgsqlParameter("idleSince", idleSince?.ToUniversalTime() ?? DBNull.Value.As()) { NpgsqlDbType = NpgsqlDbType.TimestampTz }); await command.ExecuteNonQueryAsync(); } diff --git a/src/DistributedLock.Tests/Infrastructure/Postgres/TestingPostgresProviders.cs b/src/DistributedLock.Tests/Infrastructure/Postgres/TestingPostgresProviders.cs index b7e6c57..8d89e66 100644 --- a/src/DistributedLock.Tests/Infrastructure/Postgres/TestingPostgresProviders.cs +++ b/src/DistributedLock.Tests/Infrastructure/Postgres/TestingPostgresProviders.cs @@ -1,4 +1,5 @@ -using Medallion.Threading.Postgres; +using Medallion.Threading.Internal; +using Medallion.Threading.Postgres; using Medallion.Threading.Tests.Data; namespace Medallion.Threading.Tests.Postgres; @@ -15,7 +16,7 @@ public override IDistributedLock CreateLockWithExactName(string name) => ToPostgresOptions(options) ), connection => new PostgresDistributedLock(new PostgresAdvisoryLockKey(name, allowHashing: false), connection), - transaction => new PostgresDistributedLock(new PostgresAdvisoryLockKey(name, allowHashing: false), transaction.Connection) + transaction => new PostgresDistributedLock(new PostgresAdvisoryLockKey(name, allowHashing: false), transaction.Connection!) ); public override string GetSafeName(string name) => new PostgresAdvisoryLockKey(name, allowHashing: true).ToString(); @@ -23,6 +24,7 @@ public override IDistributedLock CreateLockWithExactName(string name) => internal static Action ToPostgresOptions((bool useMultiplexing, bool useTransaction, TimeSpan? keepaliveCadence) options) => o => { o.UseMultiplexing(options.useMultiplexing); + o.UseTransaction(options.useTransaction); if (options.keepaliveCadence is { } keepaliveCadence) { o.KeepaliveCadence(keepaliveCadence); } }; } @@ -40,7 +42,7 @@ public override IDistributedReaderWriterLock CreateReaderWriterLockWithExactName TestingPostgresDistributedLockProvider.ToPostgresOptions(options) ), connection => new PostgresDistributedReaderWriterLock(new PostgresAdvisoryLockKey(name, allowHashing: false), connection), - transaction => new PostgresDistributedReaderWriterLock(new PostgresAdvisoryLockKey(name, allowHashing: false), transaction.Connection) + transaction => new PostgresDistributedReaderWriterLock(new PostgresAdvisoryLockKey(name, allowHashing: false), transaction.Connection!) ); public override string GetSafeName(string name) => new PostgresAdvisoryLockKey(name, allowHashing: true).ToString(); diff --git a/src/DistributedLock.Tests/Infrastructure/Redis/RedisServer.cs b/src/DistributedLock.Tests/Infrastructure/Redis/RedisServer.cs index 078d9ba..d524205 100644 --- a/src/DistributedLock.Tests/Infrastructure/Redis/RedisServer.cs +++ b/src/DistributedLock.Tests/Infrastructure/Redis/RedisServer.cs @@ -9,7 +9,7 @@ internal class RedisServer private static readonly int MinDynamicPort = RedisPorts.DefaultPorts.Max() + 1, MaxDynamicPort = MinDynamicPort + 100; // it's important for this to be lazy because it doesn't work when running on Linux - private static readonly Lazy WslPath = new Lazy( + private static readonly Lazy WslPath = new( () => Directory.GetDirectories(@"C:\Windows\WinSxS") .Select(d => Path.Combine(d, "wsl.exe")) .Where(File.Exists) @@ -17,7 +17,7 @@ internal class RedisServer .First() ); - private static readonly Dictionary ActiveServersByPort = new Dictionary(); + private static readonly Dictionary ActiveServersByPort = []; private static readonly RedisServer[] DefaultServers = new RedisServer[RedisPorts.DefaultPorts.Count]; private readonly Command _command; @@ -30,12 +30,12 @@ private RedisServer(int? port, bool allowAdmin) { this.Port = port ?? Enumerable.Range(MinDynamicPort, count: MaxDynamicPort - MinDynamicPort + 1) .First(p => !ActiveServersByPort.ContainsKey(p)); - this._command = Command.Run(WslPath.Value, new object[] { "redis-server", "--port", this.Port }, options: o => o.StartInfo(si => si.RedirectStandardInput = false)) + this._command = Command.Run(WslPath.Value, ["redis-server", "--port", this.Port], options: o => o.StartInfo(si => si.RedirectStandardInput = false)) .RedirectTo(Console.Out) .RedirectStandardErrorTo(Console.Error); ActiveServersByPort.Add(this.Port, this); } - this.Multiplexer = ConnectionMultiplexer.Connect($"localhost:{this.Port}{(allowAdmin ? ",allowAdmin=true" : string.Empty)}"); + this.Multiplexer = ConnectionMultiplexer.Connect($"localhost:{this.Port},abortConnect=false{(allowAdmin ? ",allowAdmin=true" : string.Empty)}"); // Clean the db to ensure it is empty. Running an arbitrary command also ensures that // the db successfully spun up before we proceed (Connect seemingly can complete before that happens). // This is particularly important for cross-process locking where the lock taker process @@ -62,15 +62,21 @@ public static void DisposeAll() var shutdownTasks = ActiveServersByPort.Values .Select(async server => { + // When testing the case of a server outage, we'll have manually shut down some servers. + // In that case, we shouldn't attempt to connect to them since that will fail. + var isConnected = server.Multiplexer.GetServers().Any(s => s.IsConnected); server.Multiplexer.Dispose(); try { - using var adminMultiplexer = await ConnectionMultiplexer.ConnectAsync($"localhost:{server.Port},allowAdmin=true"); - adminMultiplexer.GetServer("localhost", server.Port).Shutdown(ShutdownMode.Never); + if (isConnected) + { + using var adminMultiplexer = await ConnectionMultiplexer.ConnectAsync($"localhost:{server.Port},allowAdmin=true"); + adminMultiplexer.GetServer("localhost", server.Port).Shutdown(ShutdownMode.Never); + } } finally { - if (!await server._command.Task.WaitAsync(TimeSpan.FromSeconds(5))) + if (!await server._command.Task.TryWaitAsync(TimeSpan.FromSeconds(5))) { server._command.Kill(); throw new InvalidOperationException("Forced to kill Redis server"); diff --git a/src/DistributedLock.Tests/Infrastructure/Shared/MariaDbCredentials.cs b/src/DistributedLock.Tests/Infrastructure/Shared/MariaDbCredentials.cs index c9747ca..045d1fc 100644 --- a/src/DistributedLock.Tests/Infrastructure/Shared/MariaDbCredentials.cs +++ b/src/DistributedLock.Tests/Infrastructure/Shared/MariaDbCredentials.cs @@ -29,7 +29,7 @@ public static string GetConnectionString(string baseDirectory) return new MySqlConnectionStringBuilder { - Port = 3307, + Port = 3306, Server = "localhost", Database = "mysql", UserID = username, diff --git a/src/DistributedLock.Tests/Infrastructure/Shared/MySqlCredentials.cs b/src/DistributedLock.Tests/Infrastructure/Shared/MySqlCredentials.cs index 2740b0e..d2b9aa0 100644 --- a/src/DistributedLock.Tests/Infrastructure/Shared/MySqlCredentials.cs +++ b/src/DistributedLock.Tests/Infrastructure/Shared/MySqlCredentials.cs @@ -21,7 +21,7 @@ public static string GetConnectionString(string baseDirectory) return new MySqlConnectionStringBuilder { - Port = 3306, + Port = 3307, Server = "localhost", Database = "mysql", UserID = username, @@ -29,6 +29,8 @@ public static string GetConnectionString(string baseDirectory) PersistSecurityInfo = true, // set a high pool size so that we don't empty the pool through things like lock abandonment tests MaximumPoolSize = 500, + // workaround for https://github.com/mysql-net/MySqlConnector/issues/1448 + TlsVersion = "Tls12" }.ConnectionString; } } diff --git a/src/DistributedLock.Tests/Infrastructure/Shared/OracleCredentials.cs b/src/DistributedLock.Tests/Infrastructure/Shared/OracleCredentials.cs index 15ff975..517f078 100644 --- a/src/DistributedLock.Tests/Infrastructure/Shared/OracleCredentials.cs +++ b/src/DistributedLock.Tests/Infrastructure/Shared/OracleCredentials.cs @@ -19,42 +19,23 @@ internal static class OracleCredentials public static string GetConnectionString(string baseDirectory) { var credentialDirectory = Path.GetFullPath(Path.Combine(baseDirectory, "..", "..", "..", "credentials")); - ConfigureWallet(credentialDirectory); - var (datasource, username, password) = GetCredentials(credentialDirectory); + var (username, password) = GetCredentials(credentialDirectory); return new OracleConnectionStringBuilder { - DataSource = datasource, + DataSource = "(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SERVICE_NAME=XE)))", UserID = username, Password = password, PersistSecurityInfo = true, - // The free-tier autonomous database only allows 20 connections maximum (presumably across all clients) so this limit - // should help keep us below this limit. Running up against the limit throws errors on Connection.Open() - MaxPoolSize = 15, }.ConnectionString; } - private static void ConfigureWallet(string credentialDirectory) - { - var walletDirectory = Directory.GetDirectories(credentialDirectory, "Wallet_*").Single(); - if (OracleConfiguration.TnsAdmin != walletDirectory) - { - // directory containing tnsnames.ora and sqlnet.ora - OracleConfiguration.TnsAdmin = walletDirectory; - } - if (OracleConfiguration.WalletLocation != walletDirectory) - { - // directory containing cwallet.sso - OracleConfiguration.WalletLocation = walletDirectory; - } - } - - private static (string DataSource, string Username, string Password) GetCredentials(string credentialDirectory) + private static (string Username, string Password) GetCredentials(string credentialDirectory) { var file = Path.Combine(credentialDirectory, "oracle.txt"); if (!File.Exists(file)) { throw new InvalidOperationException($"Unable to find Oracle credentials file {file}"); } var lines = File.ReadAllLines(file); - if (lines.Length != 3) { throw new FormatException($"{file} must contain exactly 2 lines of text"); } - return (lines[0], lines[1], lines[2]); + if (lines.Length != 2) { throw new FormatException($"{file} must contain exactly 2 lines of text"); } + return (lines[0], lines[1]); } } diff --git a/src/DistributedLock.Tests/Infrastructure/Shared/PostgresCredentials.cs b/src/DistributedLock.Tests/Infrastructure/Shared/PostgresCredentials.cs index 06b742b..3222829 100644 --- a/src/DistributedLock.Tests/Infrastructure/Shared/PostgresCredentials.cs +++ b/src/DistributedLock.Tests/Infrastructure/Shared/PostgresCredentials.cs @@ -21,7 +21,7 @@ public static string GetConnectionString(string baseDirectory) return new NpgsqlConnectionStringBuilder { - Port = 5433, + Port = 5432, Host = "localhost", Database = "postgres", Username = username, diff --git a/src/DistributedLock.Tests/Infrastructure/Shared/SqlServerCredentials.cs b/src/DistributedLock.Tests/Infrastructure/Shared/SqlServerCredentials.cs index ec75f53..d9598e3 100644 --- a/src/DistributedLock.Tests/Infrastructure/Shared/SqlServerCredentials.cs +++ b/src/DistributedLock.Tests/Infrastructure/Shared/SqlServerCredentials.cs @@ -6,12 +6,16 @@ internal static class SqlServerCredentials public static readonly string ConnectionString = new Microsoft.Data.SqlClient.SqlConnectionStringBuilder { - DataSource = @".\SQLEXPRESS", + DataSource = @"localhost", // localhost for SQL Developer, .\SQLEXPRESS for express InitialCatalog = "master", IntegratedSecurity = true, ApplicationName = ApplicationName, // set a high pool size so that we don't empty the pool through things like lock abandonment tests MaxPoolSize = 10000, + // Allows us to connect to SQLExpress with Microsoft.Data.SqlClient while still being compatible + // with System.Data.SqlClient (alternative would be building the connection string with System.Data.SqlClient + // and doing TrustServerCertificate = true). + Encrypt = false, } .ConnectionString; } diff --git a/src/DistributedLock.Tests/Infrastructure/Shared/TargetFramework.cs b/src/DistributedLock.Tests/Infrastructure/Shared/TargetFramework.cs index ed60921..a404495 100644 --- a/src/DistributedLock.Tests/Infrastructure/Shared/TargetFramework.cs +++ b/src/DistributedLock.Tests/Infrastructure/Shared/TargetFramework.cs @@ -3,9 +3,9 @@ internal static class TargetFramework { public const string Current = -#if NET471 - "net471"; -#elif NETCOREAPP3_1 - "netcoreapp3.1"; +#if NET472 + "net472"; +#elif NET8_0 + "net8.0"; #endif } diff --git a/src/DistributedLock.Tests/Infrastructure/SqlServer/TestingSqlServerDb.cs b/src/DistributedLock.Tests/Infrastructure/SqlServer/TestingSqlServerDb.cs index 5120530..a7f8327 100644 --- a/src/DistributedLock.Tests/Infrastructure/SqlServer/TestingSqlServerDb.cs +++ b/src/DistributedLock.Tests/Infrastructure/SqlServer/TestingSqlServerDb.cs @@ -12,7 +12,7 @@ public sealed class TestingSqlServerDb : TestingPrimaryClientDb, ITestingSqlServ internal static readonly string DefaultConnectionString = SqlServerCredentials.ConnectionString; private readonly Microsoft.Data.SqlClient.SqlConnectionStringBuilder _connectionStringBuilder = - new Microsoft.Data.SqlClient.SqlConnectionStringBuilder(DefaultConnectionString); + new(DefaultConnectionString); public override DbConnectionStringBuilder ConnectionStringBuilder => this._connectionStringBuilder; @@ -47,7 +47,7 @@ WHEN 5 THEN 'Snapshot' ELSE 'Unknown' END AS isolationLevel FROM sys.dm_exec_sessions WHERE session_id = @@SPID"; - return (IsolationLevel)Enum.Parse(typeof(IsolationLevel), (string)command.ExecuteScalar()); + return (IsolationLevel)Enum.Parse(typeof(IsolationLevel), (string)command.ExecuteScalar()!); } public override DbConnection CreateConnection() => new Microsoft.Data.SqlClient.SqlConnection(this.ConnectionStringBuilder.ConnectionString); @@ -94,7 +94,7 @@ @idleSince IS NULL public sealed class TestingSystemDataSqlServerDb : TestingDb, ITestingSqlServerDb { private readonly System.Data.SqlClient.SqlConnectionStringBuilder _connectionStringBuilder = - new System.Data.SqlClient.SqlConnectionStringBuilder(TestingSqlServerDb.DefaultConnectionString); + new(TestingSqlServerDb.DefaultConnectionString); public override DbConnectionStringBuilder ConnectionStringBuilder => this._connectionStringBuilder; diff --git a/src/DistributedLock.Tests/Infrastructure/TestHelper.cs b/src/DistributedLock.Tests/Infrastructure/TestHelper.cs index 16fc855..43174ad 100644 --- a/src/DistributedLock.Tests/Infrastructure/TestHelper.cs +++ b/src/DistributedLock.Tests/Infrastructure/TestHelper.cs @@ -23,7 +23,7 @@ public static bool IsHeld(this IDistributedLock @lock) return handle == null; } - public static async Task WaitAsync(this Task task, TimeoutValue timeout) + public static async Task TryWaitAsync(this Task task, TimeoutValue timeout) { if (!task.IsCompleted) { @@ -47,7 +47,7 @@ public static async Task WaitForAsync(Func> predicate, Tim using var cancellationSource = new CancellationTokenSource(); var waitForPredicateTask = WaitForPredicateAsync(); - if (!await waitForPredicateTask.WaitAsync(timeout)) + if (!await waitForPredicateTask.TryWaitAsync(timeout)) { cancellationSource.Cancel(); await waitForPredicateTask; diff --git a/src/DistributedLock.Tests/Infrastructure/TestingLockProvider.cs b/src/DistributedLock.Tests/Infrastructure/TestingLockProvider.cs index 0ceed0c..407e04c 100644 --- a/src/DistributedLock.Tests/Infrastructure/TestingLockProvider.cs +++ b/src/DistributedLock.Tests/Infrastructure/TestingLockProvider.cs @@ -3,7 +3,7 @@ public abstract class TestingLockProvider : ITestingNameProvider, IDisposable where TStrategy : TestingSynchronizationStrategy, new() { - private readonly Lazy _lazyStrategy = new Lazy(() => new TStrategy()); + private readonly Lazy _lazyStrategy = new(() => new TStrategy()); public virtual TStrategy Strategy => this._lazyStrategy.Value; diff --git a/src/DistributedLock.Tests/Infrastructure/TestingReaderWriterLockAsMutexProvider.cs b/src/DistributedLock.Tests/Infrastructure/TestingReaderWriterLockAsMutexProvider.cs index 9d4cb83..87a542b 100644 --- a/src/DistributedLock.Tests/Infrastructure/TestingReaderWriterLockAsMutexProvider.cs +++ b/src/DistributedLock.Tests/Infrastructure/TestingReaderWriterLockAsMutexProvider.cs @@ -11,7 +11,7 @@ public sealed class TestingReaderWriterLockAsMutexProvider, new() where TStrategy : TestingSynchronizationStrategy, new() { - private readonly TReaderWriterLockProvider _readerWriterLockProvider = new TReaderWriterLockProvider(); + private readonly TReaderWriterLockProvider _readerWriterLockProvider = new(); public override TStrategy Strategy => this._readerWriterLockProvider.Strategy; diff --git a/src/DistributedLock.Tests/Infrastructure/TestingSemaphoreAsMutexProvider.cs b/src/DistributedLock.Tests/Infrastructure/TestingSemaphoreAsMutexProvider.cs index a2e7c02..0bb0399 100644 --- a/src/DistributedLock.Tests/Infrastructure/TestingSemaphoreAsMutexProvider.cs +++ b/src/DistributedLock.Tests/Infrastructure/TestingSemaphoreAsMutexProvider.cs @@ -6,9 +6,9 @@ public abstract class TestingSemaphoreAsMutexProvider, new() where TStrategy : TestingSynchronizationStrategy, new() { - private readonly TSemaphoreProvider _semaphoreProvider = new TSemaphoreProvider(); - private readonly DisposableCollection _disposables = new DisposableCollection(); - private readonly HashSet _mostlyDrainedSemaphoreNames = new HashSet(); + private readonly TSemaphoreProvider _semaphoreProvider = new(); + private readonly DisposableCollection _disposables = new(); + private readonly HashSet _mostlyDrainedSemaphoreNames = new(); private readonly int _maxCount; protected TestingSemaphoreAsMutexProvider(int maxCount) diff --git a/src/DistributedLock.Tests/Infrastructure/ZooKeeper/ZooKeeperSetUpFixture.cs b/src/DistributedLock.Tests/Infrastructure/ZooKeeper/ZooKeeperSetUpFixture.cs index 6dc62d7..13fb831 100644 --- a/src/DistributedLock.Tests/Infrastructure/ZooKeeper/ZooKeeperSetUpFixture.cs +++ b/src/DistributedLock.Tests/Infrastructure/ZooKeeper/ZooKeeperSetUpFixture.cs @@ -23,12 +23,13 @@ public void OneTimeSetUp() } else { - // based on Windows install as per https://medium.com/@shaaslam/installing-apache-zookeeper-on-windows-45eda303e835 - - const string ZooKeeperHomeEnvironmentVariable = "ZOOKEEPER_HOME"; - var zooKeeperHome = Environment.GetEnvironmentVariable(ZooKeeperHomeEnvironmentVariable); - if (zooKeeperHome == null) { throw new InvalidOperationException($"Environment variable '{ZooKeeperHomeEnvironmentVariable}' is not set"); } - + var zooKeeperHome = File.ReadAllText(Path.Combine(TestContext.CurrentContext.TestDirectory, "..", "..", "..", "credentials", "zookeeper.txt")).Trim(); + if (!Directory.Exists(zooKeeperHome)) { throw new DirectoryNotFoundException(zooKeeperHome); } + // On Windows, zkServer.cmd calls zkEnv.cmd, which checks for the environment variable JAVA_HOME. + if (Environment.GetEnvironmentVariable("JAVA_HOME") is not { } javaHome || !Directory.Exists(javaHome)) + { + throw new DirectoryNotFoundException("To run ZooKeeper, you should install Java Development Kit (JDK) and set the environment variable 'JAVA_HOME' based on that."); + } var zooKeeperPath = Path.Combine(zooKeeperHome, "bin", "zkServer.cmd"); var command = Command.Run(zooKeeperPath, options: o => o.StartInfo(i => i.RedirectStandardInput = false)) diff --git a/src/DistributedLock.Tests/Tests/ApiTest.cs b/src/DistributedLock.Tests/Tests/ApiTest.cs index d0db0be..1e188ba 100644 --- a/src/DistributedLock.Tests/Tests/ApiTest.cs +++ b/src/DistributedLock.Tests/Tests/ApiTest.cs @@ -108,7 +108,7 @@ public void TestLibraryFilesDoNotWriteToConsole() { var projectDirectory = Path.GetDirectoryName(Path.GetDirectoryName(CurrentFilePath())); var solutionDirectory = Path.GetDirectoryName(projectDirectory!); - var libraryCsFiles = Directory.GetFiles(solutionDirectory, "*.cs", SearchOption.AllDirectories) + var libraryCsFiles = Directory.GetFiles(solutionDirectory!, "*.cs", SearchOption.AllDirectories) .Where(f => new[] { ".Tests", "CodeGen", "DistributedLockTaker" }.All(s => f.IndexOf(s, StringComparison.OrdinalIgnoreCase) < 0)); Assert.IsEmpty( libraryCsFiles.Where(f => File.ReadAllText(f).Contains("Console.")) diff --git a/src/DistributedLock.Tests/Tests/Azure/AzureBehaviorTest.cs b/src/DistributedLock.Tests/Tests/Azure/AzureBehaviorTest.cs index 933ba52..8dbe0f5 100644 --- a/src/DistributedLock.Tests/Tests/Azure/AzureBehaviorTest.cs +++ b/src/DistributedLock.Tests/Tests/Azure/AzureBehaviorTest.cs @@ -16,58 +16,14 @@ public void TestAttemptToLeaseBlobIfDoesNotExist() { var blobClient = new BlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, Guid.NewGuid().ToString()); - Assert.Throws(() => blobClient.GetBlobLeaseClient().Acquire(TimeSpan.FromMinutes(1))) + Assert.Throws(() => blobClient.GetBlobLeaseClient().Acquire(TimeSpan.FromMinutes(1)))! .ErrorCode.ShouldEqual(AzureErrors.BlobNotFound); blobClient = new BlobClient(AzureCredentials.ConnectionString, "dne-container", Guid.NewGuid().ToString()); - Assert.Throws(() => blobClient.GetBlobLeaseClient().Acquire(TimeSpan.FromMinutes(1))) + Assert.Throws(() => blobClient.GetBlobLeaseClient().Acquire(TimeSpan.FromMinutes(1)))! .ErrorCode.ShouldEqual("ContainerNotFound"); } - [Test] - public void TestUploadToWrongBlobType([Values("block", "page", "append")] string actualType) - { - var blobName = Guid.NewGuid().ToString(); - - var createFunctions = new Dictionary - { - ["block"] = () => new BlockBlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, blobName).Upload(Stream.Null), - ["page"] = () => new PageBlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, blobName).CreateIfNotExists(size: 0), - ["append"] = () => new AppendBlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, blobName).CreateIfNotExists() - }; - - // right now append blobs aren't fully supported, so we can't fully test this - if (actualType == "append") - { - Assert.Throws(() => createFunctions[actualType]()) - .ErrorCode.ShouldEqual("FeatureNotSupportedByEmulator"); - return; - } - else - { - createFunctions.Remove("append"); // to prevent it from failing below - } - - var baseClient = new BlobBaseClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, blobName); - - Assert.IsFalse(baseClient.Exists()); - createFunctions[actualType](); - Assert.IsTrue(baseClient.Exists()); - - foreach (var kvp in createFunctions) - { - if (kvp.Key == actualType) - { - Assert.DoesNotThrow(() => kvp.Value()); - } - else - { - Assert.Throws(() => kvp.Value()) - .ErrorCode.ShouldEqual("InvalidBlobType"); - } - } - } - [Test] public void TestSlashEquivalence() { @@ -90,7 +46,7 @@ public void TestThrowsIfLeaseAlreadyHeld() client1.Upload(Stream.Null); var client2 = new BlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, name); Assert.DoesNotThrow(() => client1.GetBlobLeaseClient().Acquire(TimeSpan.FromSeconds(15))); - Assert.Throws(() => client2.GetBlobLeaseClient().Acquire(TimeSpan.FromSeconds(15))) + Assert.Throws(() => client2.GetBlobLeaseClient().Acquire(TimeSpan.FromSeconds(15)))! .ErrorCode.ShouldEqual("LeaseAlreadyPresent"); } } diff --git a/src/DistributedLock.Tests/Tests/Azure/AzureBlobLeaseDistributedLockTest.cs b/src/DistributedLock.Tests/Tests/Azure/AzureBlobLeaseDistributedLockTest.cs index 473c730..93fb16a 100644 --- a/src/DistributedLock.Tests/Tests/Azure/AzureBlobLeaseDistributedLockTest.cs +++ b/src/DistributedLock.Tests/Tests/Azure/AzureBlobLeaseDistributedLockTest.cs @@ -53,18 +53,11 @@ async ValueTask TestAsync() var name = provider.GetUniqueSafeName(); var client = CreateClient(type, name); - if (client is AppendBlobClient appendClient) - { - Assert.That( - Assert.Throws(() => 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); + await new BlobClientWrapper(new BlobClient(AzureCredentials.ConnectionString, client.BlobContainerName, client.Name)) + .CreateIfNotExistsAsync(new Dictionary(), CancellationToken.None); } var @lock = new AzureBlobLeaseDistributedLock(client); @@ -85,18 +78,10 @@ public async Task TestWrapperCreateIfNotExists([Values] BlobClientType type) var metadata = new Dictionary { ["abc"] = "123" }; - if (client is AppendBlobClient) - { - Assert.That( - Assert.ThrowsAsync(async () => await wrapper.CreateIfNotExistsAsync(metadata, CancellationToken.None)).ToString(), - Does.Contain("This feature is not currently supported by the Storage Emulator") - ); - return; - } if (client.GetType() == typeof(BlobBaseClient)) { Assert.That( - Assert.ThrowsAsync(async () => await wrapper.CreateIfNotExistsAsync(metadata, CancellationToken.None)).ToString(), + Assert.ThrowsAsync(async () => await wrapper.CreateIfNotExistsAsync(metadata, CancellationToken.None))!.ToString(), Does.Contain("Either ensure that the blob exists or use a non-base client type") ); return; @@ -121,11 +106,14 @@ public void TestCanUseLeaseIdForBlobOperations() var @lock = new AzureBlobLeaseDistributedLock(client); using var handle = @lock.Acquire(); - Assert.Throws(() => client.UploadPages(new MemoryStream(new byte[BlobSize]), offset: 0)) + Assert.Throws(() => 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 }) + () => client.UploadPages(new MemoryStream(new byte[BlobSize]), offset: 0, options: new() + { + Conditions = new PageBlobRequestConditions { LeaseId = handle.LeaseId } + }) ); handle.Dispose(); @@ -139,7 +127,7 @@ public void TestThrowsIfContainerDoesNotExist() provider.Strategy.ContainerName = "does-not-exist"; var @lock = provider.CreateLock(nameof(TestThrowsIfContainerDoesNotExist)); - Assert.Throws(() => @lock.TryAcquire()?.Dispose()) + Assert.Throws(() => @lock.TryAcquire()?.Dispose())! .ErrorCode.ShouldEqual("ContainerNotFound"); } @@ -195,8 +183,8 @@ public void TestTriggersHandleLostIfLeaseExpiresNaturally() Assert.IsTrue(@event.Wait(TimeSpan.FromSeconds(15.1))); - Assert.Throws(handle.Dispose) - .ErrorCode.ShouldEqual("LeaseLost"); + Assert.Throws(handle.Dispose)! + .ErrorCode.ShouldEqual("LeaseNotPresentWithBlobOperation"); } [Test] @@ -222,7 +210,7 @@ public void TestExitsDespiteLongSleepTime() BlobClientType.Page => new PageBlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, name), BlobClientType.Append => new AppendBlobClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, name), BlobClientType.Base => new BlobBaseClient(AzureCredentials.ConnectionString, AzureCredentials.DefaultBlobContainerName, name), - _ => throw new ArgumentException(nameof(type)), + _ => throw new ArgumentException("Bad type", nameof(type)), }; public enum BlobClientType diff --git a/src/DistributedLock.Tests/Tests/Core/DeadlockExceptionTest.cs b/src/DistributedLock.Tests/Tests/Core/DeadlockExceptionTest.cs index cb71a6d..5e26d4a 100644 --- a/src/DistributedLock.Tests/Tests/Core/DeadlockExceptionTest.cs +++ b/src/DistributedLock.Tests/Tests/Core/DeadlockExceptionTest.cs @@ -6,11 +6,12 @@ namespace Medallion.Threading.Tests.Core; [Category("CI")] public class DeadlockExceptionTest { +#if NETFRAMEWORK // binary serialization has been removed from newer versions of .NET [Test] public void TestDeadlockExceptionSerialization() { void ThrowDeadlockException() => throw new DeadlockException(nameof(TestDeadlockExceptionSerialization), new InvalidOperationException("foo")); - var deadlockException = Assert.Throws(ThrowDeadlockException); + var deadlockException = Assert.Throws(ThrowDeadlockException)!; var formatter = new BinaryFormatter(); var stream = new MemoryStream(); @@ -22,4 +23,5 @@ public void TestDeadlockExceptionSerialization() deserialized.StackTrace.ShouldEqual(deadlockException.StackTrace); (deserialized.InnerException?.Message).ShouldEqual(deadlockException.InnerException?.Message); } +#endif } diff --git a/src/DistributedLock.Tests/Tests/Core/HelpersTest.cs b/src/DistributedLock.Tests/Tests/Core/HelpersTest.cs index 8cf7480..c6aba13 100644 --- a/src/DistributedLock.Tests/Tests/Core/HelpersTest.cs +++ b/src/DistributedLock.Tests/Tests/Core/HelpersTest.cs @@ -1,5 +1,7 @@ using Medallion.Threading.Internal; using NUnit.Framework; +using System.Collections.Concurrent; +using System.Runtime.CompilerServices; namespace Medallion.Threading.Tests.Core; @@ -30,4 +32,49 @@ public void TestSafeCreateTaskReturnsCaughtExceptionAsFaultedTask() static Task GetTask(string message) => throw new TimeZoneNotFoundException(message); } + + /// + /// Based on https://github.com/madelson/DistributedLock/issues/192 + /// + [Test] + public async Task TestTryAwaitShouldNotResultInUnobservedTaskException([Values] bool faulted) + { + AsyncLocal scope = new() { Value = true }; + ConcurrentBag unobservedTaskExceptions = []; + EventHandler handler = (_, e) => unobservedTaskExceptions.Add(e.Exception); + + TaskScheduler.UnobservedTaskException += handler; + try + { + await TryAwaitFailedTask(); + GC.Collect(); + GC.WaitForPendingFinalizers(); + } + finally { TaskScheduler.UnobservedTaskException -= handler; } + + foreach (var exception in unobservedTaskExceptions) + { + Assert.That(exception.ToString(), Does.Not.Contain(nameof(TimeZoneNotFoundException))); + Assert.That(exception.ToString(), Does.Not.Contain(nameof(OperationCanceledException))); + Assert.That(exception.ToString(), Does.Not.Contain(nameof(TaskCanceledException))); + } + + [MethodImpl(MethodImplOptions.NoInlining)] + async Task TryAwaitFailedTask() + { + Task task; + if (faulted) + { + task = Task.Run(() => throw new TimeZoneNotFoundException()); + } + else + { + CancellationTokenSource cancellationSource = new(); + task = Task.Delay(TimeSpan.FromSeconds(30), cancellationSource.Token); + cancellationSource.Cancel(); + } + + await task.TryAwait(); + } + } } diff --git a/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedLockTest.cs b/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedLockTest.cs index 868873a..0005e0f 100644 --- a/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedLockTest.cs +++ b/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedLockTest.cs @@ -10,7 +10,7 @@ namespace Medallion.Threading.Tests.FileSystem; public class FileDistributedLockTest { private static readonly string LockFileDirectory = Path.Combine(Path.GetTempPath(), nameof(FileDistributedLockTest), TargetFramework.Current); - private static DirectoryInfo LockFileDirectoryInfo => new DirectoryInfo(LockFileDirectory); + private static DirectoryInfo LockFileDirectoryInfo => new(LockFileDirectory); [OneTimeSetUp] public void OneTimeSetUp() @@ -116,10 +116,20 @@ public void TestThrowsIfProvidedFileNameIsAlreadyADirectory() var @lock = new FileDistributedLock(LockFileDirectoryInfo, nameof(TestThrowsIfProvidedFileNameIsAlreadyADirectory)); Directory.CreateDirectory(@lock.Name); - var exception = Assert.Throws(() => @lock.Acquire().Dispose()); + var exception = Assert.Throws(() => @lock.Acquire().Dispose())!; Assert.That(exception.Message, Does.Contain("because it is already the name of a directory")); } + [Test] + public void TestThrowsIfProvidedDirectoryIsAlreadyFile() + { + var tempFile = Path.GetTempFileName(); + + var @lock = new FileDistributedLock(lockFileDirectory: new(tempFile), "some name"); + var exception = Assert.Throws(() => @lock.Acquire().Dispose())!; + Assert.That(exception.InnerException!.Message, Does.Match("file .* already exists")); + } + [Test] public void TestEmptyNameIsAllowed() => AssertCanUseName(string.Empty); @@ -238,7 +248,10 @@ public void TestReservedWindowsNamesAreAllowed(string name) { AssertCanUseName(variant); - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) + // Restrictions were alleviated in Win11: https://superuser.com/a/1742520/281669 + // Win <= 10 detection: see https://stackoverflow.com/a/69038652/1142970 + && Environment.OSVersion.Version.Build < 22000) { Assert.IsFalse(CanCreateFileWithName(variant), variant); Assert.AreNotEqual(name, Path.GetFileName(new FileDistributedLock(LockFileDirectoryInfo, name).Name), variant); diff --git a/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedLockWindowsTest.cs b/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedLockWindowsTest.cs index 2ca5174..174bf2e 100644 --- a/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedLockWindowsTest.cs +++ b/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedLockWindowsTest.cs @@ -24,7 +24,7 @@ public void TestThrowsUnauthorizedAccessExceptionInCaseOfFilePermissionViolation public void TestThrowsUnauthorizedAccessExceptionInCaseOfDirectoryPermissionViolation() { var @lock = new FileDistributedLock(new DirectoryInfo(@"C:\Windows\MedallionDistributedLock"), Guid.NewGuid().ToString()); - var exception = Assert.Throws(() => @lock.TryAcquire()?.Dispose()); + var exception = Assert.Throws(() => @lock.TryAcquire()?.Dispose())!; Assert.IsInstanceOf(exception.InnerException); Assert.IsFalse(Directory.Exists(Path.GetDirectoryName(@lock.Name))); } diff --git a/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedSynchronizationProviderTest.cs b/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedSynchronizationProviderTest.cs index 1ab631d..d74b9f7 100644 --- a/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedSynchronizationProviderTest.cs +++ b/src/DistributedLock.Tests/Tests/FileSystem/FileDistributedSynchronizationProviderTest.cs @@ -6,7 +6,7 @@ namespace Medallion.Threading.Tests.FileSystem; public class FileDistributedSynchronizationProviderTest { private static readonly string LockFileDirectory = Path.Combine(Path.GetTempPath(), nameof(FileDistributedSynchronizationProviderTest), TargetFramework.Current); - private static DirectoryInfo LockFileDirectoryInfo => new DirectoryInfo(LockFileDirectory); + private static DirectoryInfo LockFileDirectoryInfo => new(LockFileDirectory); [OneTimeSetUp] public void OneTimeSetUp() diff --git a/src/DistributedLock.Tests/Tests/MySql/MySqlDistributedLockTest.cs b/src/DistributedLock.Tests/Tests/MySql/MySqlDistributedLockTest.cs index 47d98ae..a706f1f 100644 --- a/src/DistributedLock.Tests/Tests/MySql/MySqlDistributedLockTest.cs +++ b/src/DistributedLock.Tests/Tests/MySql/MySqlDistributedLockTest.cs @@ -51,22 +51,22 @@ public async Task TestMySqlCommandMustExplicitlyParticipateInTransaction(Type te await connection.OpenAsync(); using var createTableCommand = connection.CreateCommand(); - createTableCommand.CommandText = "CREATE TEMPORARY TABLE world.temp (id INT)"; + createTableCommand.CommandText = "CREATE TEMPORARY TABLE distributed_lock.temp (id INT)"; await createTableCommand.ExecuteNonQueryAsync(); using var transaction = connection.BeginTransaction(); using var commandInTransaction = connection.CreateCommand(); commandInTransaction.Transaction = transaction; - commandInTransaction.CommandText = @"INSERT INTO world.temp (id) VALUES (1), (2)"; + commandInTransaction.CommandText = @"INSERT INTO distributed_lock.temp (id) VALUES (1), (2)"; await commandInTransaction.ExecuteNonQueryAsync(); using var commandOutsideTransaction = connection.CreateCommand(); - commandOutsideTransaction.CommandText = "SELECT COUNT(*) FROM world.temp"; - var exception = Assert.ThrowsAsync(() => commandOutsideTransaction.ExecuteScalarAsync()); + commandOutsideTransaction.CommandText = "SELECT COUNT(*) FROM distributed_lock.temp"; + var exception = Assert.ThrowsAsync(commandOutsideTransaction.ExecuteScalarAsync)!; Assert.That(exception.Message, Does.Contain("The transaction associated with this command is not the connection's active transaction")); - commandInTransaction.CommandText = "SELECT COUNT(*) FROM world.temp"; + commandInTransaction.CommandText = "SELECT COUNT(*) FROM distributed_lock.temp"; (await commandInTransaction.ExecuteScalarAsync()).ShouldEqual(2); } } diff --git a/src/DistributedLock.Tests/Tests/MySql/MySqlDistributedSynchronizationProviderTest.cs b/src/DistributedLock.Tests/Tests/MySql/MySqlDistributedSynchronizationProviderTest.cs index 1d185d3..a7a6405 100644 --- a/src/DistributedLock.Tests/Tests/MySql/MySqlDistributedSynchronizationProviderTest.cs +++ b/src/DistributedLock.Tests/Tests/MySql/MySqlDistributedSynchronizationProviderTest.cs @@ -1,4 +1,5 @@ using Medallion.Threading.MySql; +using Medallion.Threading.Tests.Data; using NUnit.Framework; using System.Data; @@ -15,18 +16,16 @@ public void TestArgumentValidation() } [Test] - public async Task BasicTest() + public async Task BasicTest([Values(typeof(TestingMySqlDb), typeof(TestingMariaDbDb))] Type dbType) { - foreach (var db in new[] { new TestingMySqlDb(), new TestingMariaDbDb() }) - { - var provider = new MySqlDistributedSynchronizationProvider(db.ConnectionString); + var db = (TestingDb)Activator.CreateInstance(dbType)!; + var provider = new MySqlDistributedSynchronizationProvider(db.ConnectionString); - const string LockName = TargetFramework.Current + "ProviderBasicTest"; - await using (await provider.AcquireLockAsync(LockName)) - { - await using var handle = await provider.TryAcquireLockAsync(LockName); - Assert.IsNull(handle, db.GetType().Name); - } + const string LockName = TargetFramework.Current + "ProviderBasicTest"; + await using (await provider.AcquireLockAsync(LockName)) + { + await using var handle = await provider.TryAcquireLockAsync(LockName); + Assert.IsNull(handle, db.GetType().Name); } } } diff --git a/src/DistributedLock.Tests/Tests/Postgres/PostgresBehaviorTest.cs b/src/DistributedLock.Tests/Tests/Postgres/PostgresBehaviorTest.cs index 5c7cdeb..dd753f8 100644 --- a/src/DistributedLock.Tests/Tests/Postgres/PostgresBehaviorTest.cs +++ b/src/DistributedLock.Tests/Tests/Postgres/PostgresBehaviorTest.cs @@ -22,9 +22,9 @@ public async Task TestPostgresCommandAutomaticallyParticipatesInTransaction() await connection.OpenAsync(); using var transaction = -#if NETCOREAPP3_1 +#if NETCOREAPP await connection.BeginTransactionAsync(); -#elif NET471 +#elif NETFRAMEWORK connection.BeginTransaction(); #endif @@ -109,7 +109,7 @@ public async Task TestCanDetectTransactionWithBeginTransactionException() using var transaction = connection.BeginTransaction(); - var ex = Assert.Throws(() => connection.BeginTransaction().Dispose()); + var ex = Assert.Throws(() => connection.BeginTransaction().Dispose())!; Assert.That(ex.Message, Does.Contain("A transaction is already in progress")); } @@ -121,7 +121,7 @@ public async Task TestDoesNotDetectConnectionBreakViaState() using var getPidCommand = connection.CreateCommand(); getPidCommand.CommandText = "SELECT pg_backend_pid()"; - var pid = (int)(await getPidCommand.ExecuteScalarAsync()); + var pid = (int)(await getPidCommand.ExecuteScalarAsync())!; var stateChangedEvent = new ManualResetEventSlim(initialState: false); connection.StateChange += (_, _2) => stateChangedEvent.Set(); @@ -151,7 +151,7 @@ public async Task TestExecutingQueryOnKilledConnectionFiresStateChanged() using var getPidCommand = connection.CreateCommand(); getPidCommand.CommandText = "SELECT pg_backend_pid()"; - var pid = (int)(await getPidCommand.ExecuteScalarAsync()); + var pid = (int)(await getPidCommand.ExecuteScalarAsync())!; Assert.AreEqual(ConnectionState.Open, connection.State); @@ -162,7 +162,7 @@ public async Task TestExecutingQueryOnKilledConnectionFiresStateChanged() killCommand.CommandText = $"SELECT pg_terminate_backend({pid})"; await killCommand.ExecuteNonQueryAsync(); - Assert.ThrowsAsync(() => getPidCommand.ExecuteScalarAsync()); + Assert.ThrowsAsync(getPidCommand.ExecuteScalarAsync); Assert.AreNotEqual(ConnectionState.Open, connection.State); Assert.IsTrue(stateChangedEvent.Wait(TimeSpan.FromSeconds(5))); diff --git a/src/DistributedLock.Tests/Tests/Postgres/PostgresConnectionOptionsBuilderTest.cs b/src/DistributedLock.Tests/Tests/Postgres/PostgresConnectionOptionsBuilderTest.cs index 902d5e0..bef6457 100644 --- a/src/DistributedLock.Tests/Tests/Postgres/PostgresConnectionOptionsBuilderTest.cs +++ b/src/DistributedLock.Tests/Tests/Postgres/PostgresConnectionOptionsBuilderTest.cs @@ -12,6 +12,8 @@ public void TestValidatesArguments() var builder = new PostgresConnectionOptionsBuilder(); Assert.Throws(() => builder.KeepaliveCadence(TimeSpan.FromMilliseconds(-2))); Assert.Throws(() => builder.KeepaliveCadence(TimeSpan.MaxValue)); + + Assert.Throws(() => PostgresConnectionOptionsBuilder.GetOptions(o => o.UseMultiplexing().UseTransaction())); } [Test] @@ -20,6 +22,15 @@ public void TestDefaults() var options = PostgresConnectionOptionsBuilder.GetOptions(null); Assert.IsTrue(options.keepaliveCadence.IsInfinite); Assert.IsTrue(options.useMultiplexing); + Assert.IsFalse(options.useTransaction); options.ShouldEqual(PostgresConnectionOptionsBuilder.GetOptions(o => { })); } + + [Test] + public void TestUseTransactionDoesNotRequireDisablingMultiplexing() + { + var options = PostgresConnectionOptionsBuilder.GetOptions(o => o.UseTransaction()); + Assert.IsTrue(options.useTransaction); + Assert.IsFalse(options.useMultiplexing); + } } diff --git a/src/DistributedLock.Tests/Tests/Postgres/PostgresDistributedLockTest.cs b/src/DistributedLock.Tests/Tests/Postgres/PostgresDistributedLockTest.cs index e31eea5..4a823f0 100644 --- a/src/DistributedLock.Tests/Tests/Postgres/PostgresDistributedLockTest.cs +++ b/src/DistributedLock.Tests/Tests/Postgres/PostgresDistributedLockTest.cs @@ -69,7 +69,7 @@ public async Task TestWorksWithAmbientTransaction() static Task GetTimeoutAsync(NpgsqlCommand command) { command.CommandText = "SHOW statement_timeout"; - return command.ExecuteScalarAsync(); + return command.ExecuteScalarAsync()!; } } } diff --git a/src/DistributedLock.Tests/Tests/Redis/RedisDistributedLockTest.cs b/src/DistributedLock.Tests/Tests/Redis/RedisDistributedLockTest.cs index e56754f..6ea2d75 100644 --- a/src/DistributedLock.Tests/Tests/Redis/RedisDistributedLockTest.cs +++ b/src/DistributedLock.Tests/Tests/Redis/RedisDistributedLockTest.cs @@ -2,13 +2,13 @@ using Moq; using NUnit.Framework; using StackExchange.Redis; +using System.Globalization; namespace Medallion.Threading.Tests.Redis; -[Category("CI")] public class RedisDistributedLockTest { - [Test] + [Test, Category("CI")] public void TestName() { const string Name = "\0🐉汉字\b\r\n\\"; @@ -17,7 +17,7 @@ public void TestName() @lock.Key.ShouldEqual(new RedisKey(Name)); } - [Test] + [Test, Category("CI")] public void TestValidatesConstructorParameters() { var database = new Mock(MockBehavior.Strict).Object; @@ -28,4 +28,32 @@ public void TestValidatesConstructorParameters() Assert.Throws(() => new RedisDistributedLock("key", new[] { database, null! })); Assert.Throws(() => new RedisDistributedLock("key", Enumerable.Empty())); } + + /// + /// Reproduces the bug in https://github.com/madelson/DistributedLock/issues/162 + /// where a Redis lock couldn't be acquired if the current CultureInfo was tr-TR, + /// due to a bug in the underlying StackExchange.Redis package. + /// + /// This is because there are both "dotted i" and "dotless i" in some Turkic languages: + /// https://en.wikipedia.org/wiki/Dotted_and_dotless_I_in_computing + /// + [Test] + public async Task TestCanAcquireLockWhenCurrentCultureIsTurkishTurkey() + { + var originalCultureInfo = CultureInfo.CurrentCulture; + + try + { + CultureInfo.CurrentCulture = CultureInfo.GetCultureInfo("tr-TR"); + var @lock = new RedisDistributedLock( + TestHelper.UniqueName, + RedisServer.GetDefaultServer(0).Multiplexer.GetDatabase() + ); + await (await @lock.AcquireAsync()).DisposeAsync(); + } + finally + { + CultureInfo.CurrentCulture = originalCultureInfo; + } + } } diff --git a/src/DistributedLock.Tests/Tests/Redis/RedisDistributedReaderWriterLockTest.cs b/src/DistributedLock.Tests/Tests/Redis/RedisDistributedReaderWriterLockTest.cs index bac045b..cc5189b 100644 --- a/src/DistributedLock.Tests/Tests/Redis/RedisDistributedReaderWriterLockTest.cs +++ b/src/DistributedLock.Tests/Tests/Redis/RedisDistributedReaderWriterLockTest.cs @@ -44,11 +44,11 @@ public async Task TestCanExtendReadLock() var writeHandleTask = @lock.AcquireWriteLockAsync().AsTask(); _ = writeHandleTask.ContinueWith(t => t.Result.Dispose()); // ensure cleanup - Assert.IsFalse(await writeHandleTask.WaitAsync(TimeSpan.FromSeconds(.5))); + Assert.IsFalse(await writeHandleTask.TryWaitAsync(TimeSpan.FromSeconds(.5))); await readHandle.DisposeAsync(); - Assert.IsTrue(await writeHandleTask.WaitAsync(TimeSpan.FromSeconds(5))); + Assert.IsTrue(await writeHandleTask.TryWaitAsync(TimeSpan.FromSeconds(5))); } [Test] diff --git a/src/DistributedLock.Tests/Tests/SqlServer/SqlConnectionOptionsBuilderTest.cs b/src/DistributedLock.Tests/Tests/SqlServer/SqlConnectionOptionsBuilderTest.cs index 12709c1..cb167f6 100644 --- a/src/DistributedLock.Tests/Tests/SqlServer/SqlConnectionOptionsBuilderTest.cs +++ b/src/DistributedLock.Tests/Tests/SqlServer/SqlConnectionOptionsBuilderTest.cs @@ -25,4 +25,12 @@ public void TestDefaults() Assert.IsFalse(options.useTransaction); options.ShouldEqual(SqlConnectionOptionsBuilder.GetOptions(o => { })); } + + [Test] + public void TestUseTransactionDoesNotRequireDisablingMultiplexing() + { + var options = SqlConnectionOptionsBuilder.GetOptions(o => o.UseTransaction()); + Assert.IsTrue(options.useTransaction); + Assert.IsFalse(options.useMultiplexing); + } } diff --git a/src/DistributedLock.Tests/Tests/SqlServer/SqlDatabaseConnectionTest.cs b/src/DistributedLock.Tests/Tests/SqlServer/SqlDatabaseConnectionTest.cs index 25d2897..3e8b2dc 100644 --- a/src/DistributedLock.Tests/Tests/SqlServer/SqlDatabaseConnectionTest.cs +++ b/src/DistributedLock.Tests/Tests/SqlServer/SqlDatabaseConnectionTest.cs @@ -66,7 +66,7 @@ public async Task TestExecuteNonQueryCanCancel([Values] bool isAsync, [Values] b } private static SqlDatabaseConnection CreateConnection(bool isSystemDataSqlClient) => - new SqlDatabaseConnection( + new( isSystemDataSqlClient ? new System.Data.SqlClient.SqlConnection(TestingSqlServerDb.DefaultConnectionString).As() : new Microsoft.Data.SqlClient.SqlConnection(TestingSqlServerDb.DefaultConnectionString), diff --git a/src/DistributedLock.Tests/Tests/SqlServer/SqlDistributedLockTest.cs b/src/DistributedLock.Tests/Tests/SqlServer/SqlDistributedLockTest.cs index bea7104..b3f3cf2 100644 --- a/src/DistributedLock.Tests/Tests/SqlServer/SqlDistributedLockTest.cs +++ b/src/DistributedLock.Tests/Tests/SqlServer/SqlDistributedLockTest.cs @@ -50,7 +50,7 @@ public async Task TestSqlCommandMustParticipateInTransaction() using var commandOutsideTransaction = connection.CreateCommand(); commandOutsideTransaction.CommandText = "SELECT 2"; - var exception = Assert.ThrowsAsync(() => commandOutsideTransaction.ExecuteScalarAsync()); + var exception = Assert.ThrowsAsync(() => commandOutsideTransaction.ExecuteScalarAsync())!; Assert.That(exception.Message, Does.Contain("requires the command to have a transaction when the connection assigned to the command is in a pending local transaction")); commandInTransaction.CommandText = "SELECT COUNT(*) FROM foo"; diff --git a/src/DistributedLock.Tests/Tests/SqlServer/SqlDistributedSemaphoreTest.cs b/src/DistributedLock.Tests/Tests/SqlServer/SqlDistributedSemaphoreTest.cs index 8c675f6..7536704 100644 --- a/src/DistributedLock.Tests/Tests/SqlServer/SqlDistributedSemaphoreTest.cs +++ b/src/DistributedLock.Tests/Tests/SqlServer/SqlDistributedSemaphoreTest.cs @@ -88,7 +88,7 @@ public void TestTicketsTakenOnBothConnectionAndTransactionForThatConnection() ); var handle2 = semaphore2.Acquire(); semaphore2.TryAcquire().ShouldEqual(null); - var ex = Assert.Catch(() => semaphore2.Acquire()); + var ex = Assert.Catch(() => semaphore2.Acquire())!; ex.Message.Contains("Deadlock").ShouldEqual(true, ex.ToString()); } diff --git a/src/DistributedLock.Tests/Tests/WaitHandles/EventWaitHandleDistributedLockTest.cs b/src/DistributedLock.Tests/Tests/WaitHandles/EventWaitHandleDistributedLockTest.cs index 0dcae3e..842a381 100644 --- a/src/DistributedLock.Tests/Tests/WaitHandles/EventWaitHandleDistributedLockTest.cs +++ b/src/DistributedLock.Tests/Tests/WaitHandles/EventWaitHandleDistributedLockTest.cs @@ -20,7 +20,7 @@ public Type TestBadName(string? name, NameStyle nameStyle) this.TestWorkingName(name, NameStyle.Safe); // should always work } - return Assert.Catch(() => CreateLock(name!, nameStyle)).GetType(); + return Assert.Catch(() => CreateLock(name!, nameStyle))!.GetType(); } [TestCase(" \t", NameStyle.AddPrefix)] @@ -42,7 +42,7 @@ public void TestMaxLengthNames() public void TestGarbageCollection() { var @lock = CreateLock("gc_test", NameStyle.AddPrefix); - WeakReference AbandonLock() => new WeakReference(@lock.Acquire()); + WeakReference AbandonLock() => new(@lock.Acquire()); var weakHandle = AbandonLock(); GC.Collect(); @@ -73,7 +73,7 @@ public void TestGetSafeLockNameCompat() } private static EventWaitHandleDistributedLock CreateLock(string name, NameStyle nameStyle) => - new EventWaitHandleDistributedLock( + new( (nameStyle == NameStyle.AddPrefix ? DistributedWaitHandleHelpers.GlobalPrefix + name : name), abandonmentCheckCadence: TimeSpan.FromSeconds(.3), exactName: nameStyle != NameStyle.Safe diff --git a/src/DistributedLock.Tests/Tests/WaitHandles/WaitHandleDistributedSemaphoreTest.cs b/src/DistributedLock.Tests/Tests/WaitHandles/WaitHandleDistributedSemaphoreTest.cs index 4dc082f..2e14524 100644 --- a/src/DistributedLock.Tests/Tests/WaitHandles/WaitHandleDistributedSemaphoreTest.cs +++ b/src/DistributedLock.Tests/Tests/WaitHandles/WaitHandleDistributedSemaphoreTest.cs @@ -21,7 +21,7 @@ public Type TestBadName(string? name, NameStyle nameStyle) this.TestWorkingName(name, NameStyle.Safe); // should always work } - return Assert.Catch(() => CreateAsLock(name!, nameStyle)).GetType(); + return Assert.Catch(() => CreateAsLock(name!, nameStyle))!.GetType(); } [TestCase(" \t", NameStyle.AddPrefix)] diff --git a/src/DistributedLock.Tests/Tests/ZooKeeper/ZooKeeperConnectionTest.cs b/src/DistributedLock.Tests/Tests/ZooKeeper/ZooKeeperConnectionTest.cs index 1069b2c..bf0158e 100644 --- a/src/DistributedLock.Tests/Tests/ZooKeeper/ZooKeeperConnectionTest.cs +++ b/src/DistributedLock.Tests/Tests/ZooKeeper/ZooKeeperConnectionTest.cs @@ -98,7 +98,7 @@ public void TestThreadSafety() } private static ZooKeeperConnectionInfo GetConnectionInfo(TimeoutValue? connectTimeout = null) => - new ZooKeeperConnectionInfo( + new( ZooKeeperPorts.DefaultConnectionString, ConnectTimeout: connectTimeout ?? TimeSpan.FromSeconds(30), SessionTimeout: TimeSpan.FromSeconds(30), diff --git a/src/DistributedLock.Tests/packages.lock.json b/src/DistributedLock.Tests/packages.lock.json new file mode 100644 index 0000000..5d05f88 --- /dev/null +++ b/src/DistributedLock.Tests/packages.lock.json @@ -0,0 +1,1208 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.7.2": { + "MedallionShell.StrongName": { + "type": "Direct", + "requested": "[1.6.2, )", + "resolved": "1.6.2", + "contentHash": "x7kIh8HiLHQrm5tcLEwNXhYfIHjQoK8ZS9MPx/LcCgNubtfFVJZm8Kk5/FSOalHjlXizcLAm6733L691l8cr/Q==" + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[17.9.0, )", + "resolved": "17.9.0", + "contentHash": "7GUNAUbJYn644jzwLm5BD3a2p9C1dmP8Hr6fDPDxgItQk9hBs1Svdxzz07KQ/UphMSmgza9AbijBJGmw5D658A==", + "dependencies": { + "Microsoft.CodeCoverage": "17.9.0" + } + }, + "Moq": { + "type": "Direct", + "requested": "[4.20.70, )", + "resolved": "4.20.70", + "contentHash": "4rNnAwdpXJBuxqrOCzCyICXHSImOTRktCgCWXWykuF1qwoIsVvEnR7PjbMk/eLOxWvhmj5Kwt+kDV3RGUYcNwg==", + "dependencies": { + "Castle.Core": "5.1.1", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "NUnit": { + "type": "Direct", + "requested": "[3.14.0, )", + "resolved": "3.14.0", + "contentHash": "R7iPwD7kbOaP3o2zldWJbWeMQAvDKD0uld27QvA3PAALl1unl7x0v2J7eGiJOYjimV/BuGT4VJmr45RjS7z4LA==" + }, + "NUnit3TestAdapter": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "s8JpqTe9bI2f49Pfr3dFRfoVSuFQyraTj68c3XXjIS/MRGvvkLnrg6RLqnTjdShX+AdFUCCU/4Xex58AdUfs6A==" + }, + "System.Data.SqlClient": { + "type": "Direct", + "requested": "[4.8.6, )", + "resolved": "4.8.6", + "contentHash": "2Ij/LCaTQRyAi5lAv7UUTV9R2FobC8xN9mE0fXBZohum/xLl8IZVmE98Rq5ugQHjCgTBRKqpXRb4ORulRdA6Ig==" + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.36.0", + "contentHash": "vwqFZdHS4dzPlI7FFRkPx9ctA+aGGeRev3gnzG8lntWvKMmBhAmulABi1O9CEvS3/jzYt7yA+0pqVdxkpAd7dQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.10.3", + "contentHash": "l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==", + "dependencies": { + "Azure.Core": "1.35.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.Identity.Client.Extensions.Msal": "4.56.0", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.7.0", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.18.1", + "contentHash": "ohCslqP9yDKIn+DVjBEOBuieB1QwsUCz+BwHYNaJ3lcIsTSiI4Evnq81HcKe8CqM8qvdModbipVQKpnxpbdWqA==", + "dependencies": { + "Azure.Core": "1.36.0", + "System.IO.Hashing": "6.0.0" + } + }, + "Castle.Core": { + "type": "Transitive", + "resolved": "5.1.1", + "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==" + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Bcl.HashCode": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "MalY0Y/uM/LjXtHfX/26l2VtN4LDNZ2OE3aumNOHDLsT4fNYy2hiHXI4CXCqKpNUNm7iJ2brrc4J89UdaL56FA==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "17.9.0", + "contentHash": "RGD37ZSrratfScYXm7M0HjvxMxZyWZL4jm+XgMZbkIY1UPgjUpbNA/t+WTGj/rC/0Hm9A3IrH3ywbKZkOCnoZA==" + }, + "Microsoft.Data.SqlClient.SNI": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "0p2KMVc8WSC5JWgO+OdhYJiRM41dp6w2Dsd9JfEiHLPc6nyxBQgSrx9TYlbC8fRT2RK+HyWzDlv9ofFtxMOwQg==" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.22.0" + } + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==", + "dependencies": { + "Microsoft.Identity.Client": "4.56.0", + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "6.35.0", + "System.IdentityModel.Tokens.Jwt": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Oracle.ManagedDataAccess": { + "type": "Transitive", + "resolved": "21.13.0", + "contentHash": "3OaqQzmx5aRrjBfPu44BaGy9Jz+NiO8Q7x+jPrSL91nSc/M4JYv6j/aX1dwdq4rlSHAw6Ct9rUsd0z7xjvq0Gw==", + "dependencies": { + "System.Formats.Asn1": "7.0.0", + "System.Text.Json": "6.0.1" + } + }, + "Pipelines.Sockets.Unofficial": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "dependencies": { + "System.IO.Pipelines": "5.0.1" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "jXw9MlUu/kRfEU0WyTptAVueupqIeE3/rl0EZDMlf8pcvJnitQ8HeVEp69rZdaStXwTV72boi/Bhw8lOeO+U2w==", + "dependencies": { + "System.Security.Permissions": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Formats.Asn1": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "+nfpV0afLmvJW8+pLlHxRjz3oZJw4fkyU9MMEaMhCsHi/SN9bGF9q79ROubDiwTiCHezmK0uCWkPP7tGFP/4yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.ValueTuple": "4.5.0" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "System.IO.Compression": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==" + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Rfm2jYCaUeGysFEZjDe7j1R4x6Z6BzumS/vUT5a1AA/AWJuGX71PoGB0RmpyX3VmrGqVnAwtfMn39OHR8Y/5+g==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "5.0.1", + "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Runtime.InteropServices.RuntimeInformation": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "ehYW0m9ptxpGWvE4zgqongBVWpSDU/JCFD4K7krxkQwSz/sFQjEXCUqpvencjy6DYDbn7Ig09R8GFffu8TtneQ==" + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4", + "System.ValueTuple": "4.5.0" + } + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.ValueTuple": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + }, + "distributedlock": { + "type": "Project", + "dependencies": { + "DistributedLock.Azure": "[1.0.1, )", + "DistributedLock.FileSystem": "[1.0.2, )", + "DistributedLock.MySql": "[1.0.2, )", + "DistributedLock.Oracle": "[1.0.3, )", + "DistributedLock.Postgres": "[1.1.0, )", + "DistributedLock.Redis": "[1.0.3, )", + "DistributedLock.SqlServer": "[1.0.4, )", + "DistributedLock.WaitHandles": "[1.0.1, )", + "DistributedLock.ZooKeeper": "[1.0.0, )" + } + }, + "distributedlock.azure": { + "type": "Project", + "dependencies": { + "Azure.Storage.Blobs": "[12.19.1, )", + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "distributedlock.filesystem": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.mysql": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "MySqlConnector": "[2.3.5, )" + } + }, + "distributedlock.oracle": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Oracle.ManagedDataAccess": "[21.13.0, )" + } + }, + "distributedlock.postgres": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Npgsql": "[8.0.2, )" + } + }, + "distributedlock.redis": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "StackExchange.Redis": "[2.7.27, )" + } + }, + "distributedlock.sqlserver": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Microsoft.Data.SqlClient": "[5.2.0, )" + } + }, + "distributedlock.waithandles": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.zookeeper": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "ZooKeeperNetEx": "[3.4.12.4, )" + } + }, + "Azure.Storage.Blobs": { + "type": "CentralTransitive", + "requested": "[12.19.1, )", + "resolved": "12.19.1", + "contentHash": "x43hWFJ4sPQ23TD4piCwT+KlQpZT8pNDAzqj6yUCqh+WJ2qcQa17e1gh6ZOeT2QNFQTTDSuR56fm2bIV7i11/w==", + "dependencies": { + "Azure.Storage.Common": "12.18.1", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.Data.SqlClient": { + "type": "CentralTransitive", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "System.Buffers": "4.5.1", + "System.Configuration.ConfigurationManager": "6.0.1", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Text.Encodings.Web": "6.0.0" + } + }, + "MySqlConnector": { + "type": "CentralTransitive", + "requested": "[2.3.5, )", + "resolved": "2.3.5", + "contentHash": "AmEfUPkFl+Ev6jJ8Dhns3CYHBfD12RHzGYWuLt6DfG6/af6YvOMyPz74ZPPjBYQGRJkumD2Z48Kqm8s5DJuhLA==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "7.0.1", + "System.Diagnostics.DiagnosticSource": "7.0.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Npgsql": { + "type": "CentralTransitive", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "MuJzLoWCaQhQAR3oh66YR0Ir6mxuezncGX3f8wxvAc21g0+9HICktJQlqMoODhxztZKXE5k9GxRxqUAN+vPb4g==", + "dependencies": { + "Microsoft.Bcl.HashCode": "1.1.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "System.Collections.Immutable": "8.0.0", + "System.Diagnostics.DiagnosticSource": "8.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Json": "8.0.0", + "System.Threading.Channels": "8.0.0" + } + }, + "StackExchange.Redis": { + "type": "CentralTransitive", + "requested": "[2.7.27, )", + "resolved": "2.7.27", + "contentHash": "Uqc2OQHglqj9/FfGQ6RkKFkZfHySfZlfmbCl+hc+u2I/IqunfelQ7QJi7ZhvAJxUtu80pildVX6NPLdDaUffOw==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "5.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8", + "System.IO.Compression": "4.3.0", + "System.Threading.Channels": "5.0.0" + } + }, + "ZooKeeperNetEx": { + "type": "CentralTransitive", + "requested": "[3.4.12.4, )", + "resolved": "3.4.12.4", + "contentHash": "YECtByVSH7TRjQKplwOWiKyanCqYE5eEkGk5YtHJgsnbZ6+p1o0Gvs5RIsZLotiAVa6Niez1BJyKY/RDY/L6zg==" + } + }, + "net8.0": { + "MedallionShell.StrongName": { + "type": "Direct", + "requested": "[1.6.2, )", + "resolved": "1.6.2", + "contentHash": "x7kIh8HiLHQrm5tcLEwNXhYfIHjQoK8ZS9MPx/LcCgNubtfFVJZm8Kk5/FSOalHjlXizcLAm6733L691l8cr/Q==" + }, + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[17.9.0, )", + "resolved": "17.9.0", + "contentHash": "7GUNAUbJYn644jzwLm5BD3a2p9C1dmP8Hr6fDPDxgItQk9hBs1Svdxzz07KQ/UphMSmgza9AbijBJGmw5D658A==", + "dependencies": { + "Microsoft.CodeCoverage": "17.9.0", + "Microsoft.TestPlatform.TestHost": "17.9.0" + } + }, + "Moq": { + "type": "Direct", + "requested": "[4.20.70, )", + "resolved": "4.20.70", + "contentHash": "4rNnAwdpXJBuxqrOCzCyICXHSImOTRktCgCWXWykuF1qwoIsVvEnR7PjbMk/eLOxWvhmj5Kwt+kDV3RGUYcNwg==", + "dependencies": { + "Castle.Core": "5.1.1" + } + }, + "NUnit": { + "type": "Direct", + "requested": "[3.14.0, )", + "resolved": "3.14.0", + "contentHash": "R7iPwD7kbOaP3o2zldWJbWeMQAvDKD0uld27QvA3PAALl1unl7x0v2J7eGiJOYjimV/BuGT4VJmr45RjS7z4LA==", + "dependencies": { + "NETStandard.Library": "2.0.0" + } + }, + "NUnit3TestAdapter": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "s8JpqTe9bI2f49Pfr3dFRfoVSuFQyraTj68c3XXjIS/MRGvvkLnrg6RLqnTjdShX+AdFUCCU/4Xex58AdUfs6A==" + }, + "System.Data.SqlClient": { + "type": "Direct", + "requested": "[4.8.6, )", + "resolved": "4.8.6", + "contentHash": "2Ij/LCaTQRyAi5lAv7UUTV9R2FobC8xN9mE0fXBZohum/xLl8IZVmE98Rq5ugQHjCgTBRKqpXRb4ORulRdA6Ig==", + "dependencies": { + "Microsoft.Win32.Registry": "4.7.0", + "System.Security.Principal.Windows": "4.7.0", + "runtime.native.System.Data.SqlClient.sni": "4.7.0" + } + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.36.0", + "contentHash": "vwqFZdHS4dzPlI7FFRkPx9ctA+aGGeRev3gnzG8lntWvKMmBhAmulABi1O9CEvS3/jzYt7yA+0pqVdxkpAd7dQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.10.3", + "contentHash": "l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==", + "dependencies": { + "Azure.Core": "1.35.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.Identity.Client.Extensions.Msal": "4.56.0", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.7.0", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.18.1", + "contentHash": "ohCslqP9yDKIn+DVjBEOBuieB1QwsUCz+BwHYNaJ3lcIsTSiI4Evnq81HcKe8CqM8qvdModbipVQKpnxpbdWqA==", + "dependencies": { + "Azure.Core": "1.36.0", + "System.IO.Hashing": "6.0.0" + } + }, + "Castle.Core": { + "type": "Transitive", + "resolved": "5.1.1", + "contentHash": "rpYtIczkzGpf+EkZgDr9CClTdemhsrwA/W5hMoPjLkRFnXzH44zDLoovXeKtmxb1ykXK9aJVODSpiJml8CTw2g==", + "dependencies": { + "System.Diagnostics.EventLog": "6.0.0" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "yuvf07qFWFqtK3P/MRkEKLhn5r2UbSpVueRziSqj0yJQIKFwG1pq9mOayK3zE5qZCTs0CbrwL9M6R8VwqyGy2w==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "17.9.0", + "contentHash": "RGD37ZSrratfScYXm7M0HjvxMxZyWZL4jm+XgMZbkIY1UPgjUpbNA/t+WTGj/rC/0Hm9A3IrH3ywbKZkOCnoZA==" + }, + "Microsoft.CSharp": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "kaj6Wb4qoMuH3HySFJhxwQfe8R/sJsNJnANrvv8WdFPMoNbKY5htfNscv+LHCu5ipz+49m2e+WQXpLXr9XYemQ==" + }, + "Microsoft.Data.SqlClient.SNI.runtime": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "po1jhvFd+8pbfvJR/puh+fkHi0GRanAdvayh/0e47yaM6CXWZ6opUjCMFuYlAnD2LcbyvQE7fPJKvogmaUcN+w==" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" + } + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.22.0" + } + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==", + "dependencies": { + "Microsoft.Identity.Client": "4.56.0", + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "6.35.0", + "System.IdentityModel.Tokens.Jwt": "6.35.0" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==", + "dependencies": { + "Microsoft.CSharp": "4.5.0", + "Microsoft.IdentityModel.Logging": "6.35.0", + "System.Security.Cryptography.Cng": "4.5.0" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, + "Microsoft.SqlServer.Server": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "N4KeF3cpcm1PUHym1RmakkzfkEv3GRMyofVv40uXsQhCQeglr2OHNcUk2WOG51AKpGO8ynGpo9M/kFXSzghwug==" + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "17.9.0", + "contentHash": "1ilw/8vgmjLyKU+2SKXKXaOqpYFJCQfGqGz+x0cosl981VzjrY74Sv6qAJv+neZMZ9ZMxF3ArN6kotaQ4uvEBw==", + "dependencies": { + "System.Reflection.Metadata": "1.6.0" + } + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "17.9.0", + "contentHash": "Spmg7Wx49Ya3SxBjyeAR+nQpjMTKZwTwpZ7KyeOTIqI/WHNPnBU4HUvl5kuHPQAwGWqMy4FGZja1HvEwvoaDiA==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "17.9.0", + "Newtonsoft.Json": "13.0.1" + } + }, + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "KSrRMb5vNi0CWSGG1++id2ZOs/1QhRqROt+qgbEAdQuGjGrFcl4AOl4/exGPUYz2wUnU42nvJqon1T3U0kPXLA==", + "dependencies": { + "System.Security.AccessControl": "4.7.0", + "System.Security.Principal.Windows": "4.7.0" + } + }, + "Microsoft.Win32.SystemEvents": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "hqTM5628jSsQiv+HGpiq3WKBl2c8v1KZfby2J6Pr7pEPlK9waPdgEO6b8A/+/xn/yZ9ulv8HuqK71ONy2tg67A==" + }, + "NETStandard.Library": { + "type": "Transitive", + "resolved": "2.0.0", + "contentHash": "7jnbRU+L08FXKMxqUflxEXtVymWvNOrS8yHgu9s6EM8Anr6T/wIX4nZ08j/u3Asz+tCufp3YVwFSEvFTPYmBPA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.1", + "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" + }, + "Oracle.ManagedDataAccess.Core": { + "type": "Transitive", + "resolved": "3.21.130", + "contentHash": "bXNwPyAaDivO84HEYiegK7r/LleSEfA0nc70bE88wkqd1E0Q1+r/SUbJ51xOK2vk6iHbTSMuhnC79BU8svPBjQ==", + "dependencies": { + "System.Diagnostics.PerformanceCounter": "6.0.1", + "System.DirectoryServices": "6.0.1", + "System.DirectoryServices.Protocols": "6.0.2" + } + }, + "Pipelines.Sockets.Unofficial": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "dependencies": { + "System.IO.Pipelines": "5.0.1" + } + }, + "runtime.native.System.Data.SqlClient.sni": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "9kyFSIdN3T0qjDQ2R0HRXYIhS3l5psBzQi6qqhdLz+SzFyEy4sVxNOke+yyYv8Cu8rPER12c3RDjLT8wF3WBYQ==", + "dependencies": { + "runtime.win-arm64.runtime.native.System.Data.SqlClient.sni": "4.4.0", + "runtime.win-x64.runtime.native.System.Data.SqlClient.sni": "4.4.0", + "runtime.win-x86.runtime.native.System.Data.SqlClient.sni": "4.4.0" + } + }, + "runtime.win-arm64.runtime.native.System.Data.SqlClient.sni": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "LbrynESTp3bm5O/+jGL8v0Qg5SJlTV08lpIpFesXjF6uGNMWqFnUQbYBJwZTeua6E/Y7FIM1C54Ey1btLWupdg==" + }, + "runtime.win-x64.runtime.native.System.Data.SqlClient.sni": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "38ugOfkYJqJoX9g6EYRlZB5U2ZJH51UP8ptxZgdpS07FgOEToV+lS11ouNK2PM12Pr6X/PpT5jK82G3DwH/SxQ==" + }, + "runtime.win-x86.runtime.native.System.Data.SqlClient.sni": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "YhEdSQUsTx+C8m8Bw7ar5/VesXvCFMItyZF7G1AUY+OM0VPZUOeAVpJ4Wl6fydBGUYZxojTDR3I6Bj/+BPkJNA==" + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "JlYi9XVvIREURRUlGMr1F6vOFLk7YSY4p1vHo4kX3tQ0AGrjqlRWHDi66ImHhy6qwXBG3BJ6Y1QlYQ+Qz6Xgww==", + "dependencies": { + "System.Diagnostics.EventLog": "8.0.0", + "System.Security.Cryptography.ProtectedData": "8.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "KiLYDu2k2J82Q9BJpWiuQqCkFjRBWVq4jDzKKWawVi9KWzyD0XG3cmfX0vqTQlL14Wi9EufJrbL0+KCLTbqWiQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "fdYxcRjQqTTacKId/2IECojlDSFvp7LP5N78+0z/xH7v/Tuw5ZAxu23Y6PTCRinqyu2ePx+Gn1098NC6jM6d+A==" + }, + "System.Diagnostics.PerformanceCounter": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "dDl7Gx3bmSrM2k2ZIm+ucEJnLloZRyvfQF1DvfvATcGF3jtaUBiPvChma+6ZcZzxWMirN3kCywkW7PILphXyMQ==", + "dependencies": { + "System.Configuration.ConfigurationManager": "6.0.0" + } + }, + "System.DirectoryServices": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "935IbO7h5FDGYxeO3cbx/CuvBBuk/VI8sENlfmXlh1pupNOB3LAGzdYdPY8CawGJFP7KNrHK5eUlsFoz3F6cuA==", + "dependencies": { + "System.Security.AccessControl": "6.0.0", + "System.Security.Permissions": "6.0.0" + } + }, + "System.DirectoryServices.Protocols": { + "type": "Transitive", + "resolved": "6.0.2", + "contentHash": "vDDPWwHn3/DNZ+kPkdXHoada+tKPEC9bVqDOr4hK6HBSP7hGCUTA0Zw6WU5qpGaqa5M1/V+axHMIv+DNEbIf6g==" + }, + "System.Drawing.Common": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "NfuoKUiP2nUWwKZN6twGqXioIe1zVD0RIj2t976A+czLHr2nY454RwwXs6JU9Htc6mwqL6Dn/nEL3dpVf2jOhg==", + "dependencies": { + "Microsoft.Win32.SystemEvents": "6.0.0" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Rfm2jYCaUeGysFEZjDe7j1R4x6Z6BzumS/vUT5a1AA/AWJuGX71PoGB0RmpyX3VmrGqVnAwtfMn39OHR8Y/5+g==" + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "5.0.1", + "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Reflection.Metadata": { + "type": "Transitive", + "resolved": "1.6.0", + "contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ==" + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "System.Runtime.Caching": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "4TmlmvGp4kzZomm7J2HJn6IIx0UUrQyhBDyb5O1XiunZlQImXW+B8b7W/sTPcXhSf9rp5NR5aDtQllwbB5elOQ==", + "dependencies": { + "System.Configuration.ConfigurationManager": "8.0.0" + } + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==" + }, + "System.Security.Cryptography.Cng": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "WG3r7EyjUe9CMPFSs6bty5doUqT+q9pbI80hlNzo2SkPkZ4VTuZkGWjpp77JB8+uaL4DFPRdBsAY+DX3dBK92A==" + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "+TUFINV2q2ifyXauQXRwy4CiBhqvDEDZeVJU7qfxya4aRYOKzVBpN+4acx25VcPB9ywUN6C0n8drWl110PhZEg==" + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0", + "System.Windows.Extensions": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "TcMd95wcrubm9nHvJEQs70rC0H/8omiSGGpU4FQ/ZA1URIqD4pjmFJh2Mfv1yH1eHgJDWTi2hMDXwTET+zOOyg==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==" + }, + "System.Windows.Extensions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "IXoJOXIqc39AIe+CIR7koBtRGMiCt/LPM3lI+PELtDIy9XdyeSrwXFdWV9dzJ2Awl0paLWUaknLxFQ5HpHZUog==", + "dependencies": { + "System.Drawing.Common": "6.0.0" + } + }, + "distributedlock": { + "type": "Project", + "dependencies": { + "DistributedLock.Azure": "[1.0.1, )", + "DistributedLock.FileSystem": "[1.0.2, )", + "DistributedLock.MySql": "[1.0.2, )", + "DistributedLock.Oracle": "[1.0.3, )", + "DistributedLock.Postgres": "[1.1.0, )", + "DistributedLock.Redis": "[1.0.3, )", + "DistributedLock.SqlServer": "[1.0.4, )", + "DistributedLock.WaitHandles": "[1.0.1, )", + "DistributedLock.ZooKeeper": "[1.0.0, )" + } + }, + "distributedlock.azure": { + "type": "Project", + "dependencies": { + "Azure.Storage.Blobs": "[12.19.1, )", + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.core": { + "type": "Project" + }, + "distributedlock.filesystem": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.mysql": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "MySqlConnector": "[2.3.5, )" + } + }, + "distributedlock.oracle": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Oracle.ManagedDataAccess.Core": "[3.21.130, )" + } + }, + "distributedlock.postgres": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Npgsql": "[8.0.2, )" + } + }, + "distributedlock.redis": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "StackExchange.Redis": "[2.7.27, )" + } + }, + "distributedlock.sqlserver": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Microsoft.Data.SqlClient": "[5.2.0, )" + } + }, + "distributedlock.waithandles": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "System.Threading.AccessControl": "[8.0.0, )" + } + }, + "distributedlock.zookeeper": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "ZooKeeperNetEx": "[3.4.12.4, )" + } + }, + "Azure.Storage.Blobs": { + "type": "CentralTransitive", + "requested": "[12.19.1, )", + "resolved": "12.19.1", + "contentHash": "x43hWFJ4sPQ23TD4piCwT+KlQpZT8pNDAzqj6yUCqh+WJ2qcQa17e1gh6ZOeT2QNFQTTDSuR56fm2bIV7i11/w==", + "dependencies": { + "Azure.Storage.Common": "12.18.1", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.Data.SqlClient": { + "type": "CentralTransitive", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI.runtime": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "Microsoft.SqlServer.Server": "1.0.0", + "System.Configuration.ConfigurationManager": "8.0.0", + "System.Runtime.Caching": "8.0.0" + } + }, + "MySqlConnector": { + "type": "CentralTransitive", + "requested": "[2.3.5, )", + "resolved": "2.3.5", + "contentHash": "AmEfUPkFl+Ev6jJ8Dhns3CYHBfD12RHzGYWuLt6DfG6/af6YvOMyPz74ZPPjBYQGRJkumD2Z48Kqm8s5DJuhLA==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "7.0.1" + } + }, + "Npgsql": { + "type": "CentralTransitive", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "MuJzLoWCaQhQAR3oh66YR0Ir6mxuezncGX3f8wxvAc21g0+9HICktJQlqMoODhxztZKXE5k9GxRxqUAN+vPb4g==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0" + } + }, + "StackExchange.Redis": { + "type": "CentralTransitive", + "requested": "[2.7.27, )", + "resolved": "2.7.27", + "contentHash": "Uqc2OQHglqj9/FfGQ6RkKFkZfHySfZlfmbCl+hc+u2I/IqunfelQ7QJi7ZhvAJxUtu80pildVX6NPLdDaUffOw==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8" + } + }, + "System.Threading.AccessControl": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==" + }, + "ZooKeeperNetEx": { + "type": "CentralTransitive", + "requested": "[3.4.12.4, )", + "resolved": "3.4.12.4", + "contentHash": "YECtByVSH7TRjQKplwOWiKyanCqYE5eEkGk5YtHJgsnbZ6+p1o0Gvs5RIsZLotiAVa6Niez1BJyKY/RDY/L6zg==" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.WaitHandles/DistributedLock.WaitHandles.csproj b/src/DistributedLock.WaitHandles/DistributedLock.WaitHandles.csproj index 526406b..753171d 100644 --- a/src/DistributedLock.WaitHandles/DistributedLock.WaitHandles.csproj +++ b/src/DistributedLock.WaitHandles/DistributedLock.WaitHandles.csproj @@ -1,7 +1,7 @@ - netstandard2.0;netstandard2.1;net461 + netstandard2.0;netstandard2.1;net462 Medallion.Threading.WaitHandles True 4 @@ -45,9 +45,9 @@ - - - + + + @@ -58,6 +58,5 @@ - \ No newline at end of file diff --git a/src/DistributedLock.WaitHandles/WaitHandleDistributedSynchronizationProvider.cs b/src/DistributedLock.WaitHandles/WaitHandleDistributedSynchronizationProvider.cs index 2880867..709cd9b 100644 --- a/src/DistributedLock.WaitHandles/WaitHandleDistributedSynchronizationProvider.cs +++ b/src/DistributedLock.WaitHandles/WaitHandleDistributedSynchronizationProvider.cs @@ -21,7 +21,7 @@ public WaitHandleDistributedSynchronizationProvider(TimeSpan? abandonmentCheckCa /// is specified, invalid wait handle names will be escaped/hashed. /// public EventWaitHandleDistributedLock CreateLock(string name, bool exactName = false) => - new EventWaitHandleDistributedLock(name, this._abandonmentCheckCadence, exactName); + new(name, this._abandonmentCheckCadence, exactName); IDistributedLock IDistributedLockProvider.CreateLock(string name) => this.CreateLock(name); @@ -31,7 +31,7 @@ public EventWaitHandleDistributedLock CreateLock(string name, bool exactName = f /// handle names will be escaped/hashed. /// public WaitHandleDistributedSemaphore CreateSemaphore(string name, int maxCount, bool exactName = false) => - new WaitHandleDistributedSemaphore(name, maxCount, this._abandonmentCheckCadence, exactName); + new(name, maxCount, this._abandonmentCheckCadence, exactName); IDistributedSemaphore IDistributedSemaphoreProvider.CreateSemaphore(string name, int maxCount) => this.CreateSemaphore(name, maxCount); diff --git a/src/DistributedLock.WaitHandles/packages.lock.json b/src/DistributedLock.WaitHandles/packages.lock.json new file mode 100644 index 0000000..558f1ad --- /dev/null +++ b/src/DistributedLock.WaitHandles/packages.lock.json @@ -0,0 +1,276 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.ValueTuple": { + "type": "CentralTransitive", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + } + }, + ".NETStandard,Version=v2.0": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "System.Threading.AccessControl": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Security.AccessControl": "6.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + } + }, + ".NETStandard,Version=v2.1": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "System.Threading.AccessControl": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Security.AccessControl": "6.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.4.0", + "contentHash": "UiLzLW+Lw6HLed1Hcg+8jSRttrbuXv7DANVj0DkL9g6EnnzbL75EB7EWsw5uRbhxd/4YdG8li5XizGWepmG3PQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "distributedlock.core": { + "type": "Project" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.ZooKeeper/DistributedLock.ZooKeeper.csproj b/src/DistributedLock.ZooKeeper/DistributedLock.ZooKeeper.csproj index be9498b..cd5c163 100644 --- a/src/DistributedLock.ZooKeeper/DistributedLock.ZooKeeper.csproj +++ b/src/DistributedLock.ZooKeeper/DistributedLock.ZooKeeper.csproj @@ -1,7 +1,7 @@ - netstandard2.0;netstandard2.1;net461 + netstandard2.0;netstandard2.1;net462 Medallion.Threading.ZooKeeper True 4 @@ -45,25 +45,24 @@ - - - + + + all - + all - + - \ No newline at end of file diff --git a/src/DistributedLock.ZooKeeper/ZooKeeperDistributedReaderWriterLock.cs b/src/DistributedLock.ZooKeeper/ZooKeeperDistributedReaderWriterLock.cs index 3c4cf11..08196fe 100644 --- a/src/DistributedLock.ZooKeeper/ZooKeeperDistributedReaderWriterLock.cs +++ b/src/DistributedLock.ZooKeeper/ZooKeeperDistributedReaderWriterLock.cs @@ -98,7 +98,7 @@ private static async Task WaitForReadLockAcquiredOrChange(ZooKeeper zooKee private static bool HasAcquiredWriteLock(ZooKeeperSynchronizationHelper.State state) => state.SortedChildren[0].Path == state.EphemeralNodePath; - private async Task WaitForWriteLockAcquiredOrChange(ZooKeeper zooKeeper, ZooKeeperSynchronizationHelper.State state, Watcher watcher) + private static async Task WaitForWriteLockAcquiredOrChange(ZooKeeper zooKeeper, ZooKeeperSynchronizationHelper.State state, Watcher watcher) { var ephemeralNodeIndex = Array.FindIndex(state.SortedChildren, t => t.Path == state.EphemeralNodePath); var nextLowestChildNode = state.SortedChildren[ephemeralNodeIndex - 1].Path; diff --git a/src/DistributedLock.ZooKeeper/ZooKeeperDistributedSynchronizationProvider.cs b/src/DistributedLock.ZooKeeper/ZooKeeperDistributedSynchronizationProvider.cs index 7f390d3..f72eff9 100644 --- a/src/DistributedLock.ZooKeeper/ZooKeeperDistributedSynchronizationProvider.cs +++ b/src/DistributedLock.ZooKeeper/ZooKeeperDistributedSynchronizationProvider.cs @@ -33,7 +33,7 @@ public ZooKeeperDistributedSynchronizationProvider(ZooKeeperPath directoryPath, /// Creates a using the given . /// public ZooKeeperDistributedLock CreateLock(string name) => - new ZooKeeperDistributedLock(this._directoryPath, name, this._connectionString, this._options); + new(this._directoryPath, name, this._connectionString, this._options); IDistributedLock IDistributedLockProvider.CreateLock(string name) => this.CreateLock(name); @@ -41,7 +41,7 @@ public ZooKeeperDistributedLock CreateLock(string name) => /// Creates a using the given . /// public ZooKeeperDistributedReaderWriterLock CreateReaderWriterLock(string name) => - new ZooKeeperDistributedReaderWriterLock(this._directoryPath, name, this._connectionString, this._options); + new(this._directoryPath, name, this._connectionString, this._options); IDistributedReaderWriterLock IDistributedReaderWriterLockProvider.CreateReaderWriterLock(string name) => this.CreateReaderWriterLock(name); @@ -49,7 +49,7 @@ public ZooKeeperDistributedReaderWriterLock CreateReaderWriterLock(string name) /// Creates a using the given and . /// public ZooKeeperDistributedSemaphore CreateSemaphore(string name, int maxCount) => - new ZooKeeperDistributedSemaphore(this._directoryPath, name, maxCount, this._connectionString, this._options); + new(this._directoryPath, name, maxCount, this._connectionString, this._options); IDistributedSemaphore IDistributedSemaphoreProvider.CreateSemaphore(string name, int maxCount) => this.CreateSemaphore(name, maxCount); } diff --git a/src/DistributedLock.ZooKeeper/packages.lock.json b/src/DistributedLock.ZooKeeper/packages.lock.json new file mode 100644 index 0000000..e42ccc8 --- /dev/null +++ b/src/DistributedLock.ZooKeeper/packages.lock.json @@ -0,0 +1,231 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "IsExternalInit": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "jcdN7vpDwjnV7U9KGCv/oNIWHJ/RIbyrpVsLQL2qbj6Cbi5U3iafKsaMn1rP+qCbkLbkB0v6oAwbVEkqrUnlyg==" + }, + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Nullable": { + "type": "Direct", + "requested": "[1.3.1, )", + "resolved": "1.3.1", + "contentHash": "Mk4ZVDfAORTjvckQprCSehi1XgOAAlk5ez06Va/acRYEloN9t6d6zpzJRn5MEq7+RnagyFIq9r+kbWzLGd+6QA==" + }, + "ZooKeeperNetEx": { + "type": "Direct", + "requested": "[3.4.12.4, )", + "resolved": "3.4.12.4", + "contentHash": "YECtByVSH7TRjQKplwOWiKyanCqYE5eEkGk5YtHJgsnbZ6+p1o0Gvs5RIsZLotiAVa6Niez1BJyKY/RDY/L6zg==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.ValueTuple": { + "type": "CentralTransitive", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + } + }, + ".NETStandard,Version=v2.0": { + "IsExternalInit": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "jcdN7vpDwjnV7U9KGCv/oNIWHJ/RIbyrpVsLQL2qbj6Cbi5U3iafKsaMn1rP+qCbkLbkB0v6oAwbVEkqrUnlyg==" + }, + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Nullable": { + "type": "Direct", + "requested": "[1.3.1, )", + "resolved": "1.3.1", + "contentHash": "Mk4ZVDfAORTjvckQprCSehi1XgOAAlk5ez06Va/acRYEloN9t6d6zpzJRn5MEq7+RnagyFIq9r+kbWzLGd+6QA==" + }, + "ZooKeeperNetEx": { + "type": "Direct", + "requested": "[3.4.12.4, )", + "resolved": "3.4.12.4", + "contentHash": "YECtByVSH7TRjQKplwOWiKyanCqYE5eEkGk5YtHJgsnbZ6+p1o0Gvs5RIsZLotiAVa6Niez1BJyKY/RDY/L6zg==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "4.5.3", + "contentHash": "3TIsJhD1EiiT0w2CcDMN/iSSwnNnsrnbzeVHSKkaEgV85txMprmuO+Yq2AdSbeVGcg28pdNDTPK87tJhX7VFHw==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + } + }, + ".NETStandard,Version=v2.1": { + "IsExternalInit": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "jcdN7vpDwjnV7U9KGCv/oNIWHJ/RIbyrpVsLQL2qbj6Cbi5U3iafKsaMn1rP+qCbkLbkB0v6oAwbVEkqrUnlyg==" + }, + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "ZooKeeperNetEx": { + "type": "Direct", + "requested": "[3.4.12.4, )", + "resolved": "3.4.12.4", + "contentHash": "YECtByVSH7TRjQKplwOWiKyanCqYE5eEkGk5YtHJgsnbZ6+p1o0Gvs5RIsZLotiAVa6Niez1BJyKY/RDY/L6zg==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "distributedlock.core": { + "type": "Project" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLock.sln b/src/DistributedLock.sln index 699cbe6..61d17d3 100644 --- a/src/DistributedLock.sln +++ b/src/DistributedLock.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.29613.14 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34616.47 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DistributedLock", "DistributedLock\DistributedLock.csproj", "{C1F56B68-C2EE-48E5-A99B-B40D397AE34F}" EndProject @@ -35,7 +35,17 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DistributedLock.ZooKeeper", EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DistributedLock.MySql", "DistributedLock.MySql\DistributedLock.MySql.csproj", "{6C13E55C-51A7-47CD-88A5-7C8564EBCB3C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DistributedLock.Oracle", "DistributedLock.Oracle\DistributedLock.Oracle.csproj", "{1CAB9A1D-0C02-459C-A90E-47819832BD58}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DistributedLock.Oracle", "DistributedLock.Oracle\DistributedLock.Oracle.csproj", "{1CAB9A1D-0C02-459C-A90E-47819832BD58}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FC144BB6-BA58-41E6-BB7E-76069FCDD293}" + ProjectSection(SolutionItems) = preProject + .editorconfig = .editorconfig + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + Directory.Packages.props = Directory.Packages.props + FixDistributedLockCoreDependencyVersion.targets = FixDistributedLockCoreDependencyVersion.targets + package.readme.md = package.readme.md + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/src/DistributedLock/DistributedLock.csproj b/src/DistributedLock/DistributedLock.csproj index 20b3b73..495f84a 100644 --- a/src/DistributedLock/DistributedLock.csproj +++ b/src/DistributedLock/DistributedLock.csproj @@ -1,7 +1,7 @@  - netstandard2.0;netstandard2.1;net461;net462 + netstandard2.0;netstandard2.1;net462 Medallion.Threading True 4 @@ -10,7 +10,7 @@ - 2.3.4 + 2.4.0 2.0.0.0 Michael Adelson Provides easy-to-use mutexes, reader-writer locks, and semaphores that can synchronize across processes and machines. This is an umbrella package that brings in the entire family of DistributedLock.* packages (e. g. DistributedLock.SqlServer) as references. Those packages can also be installed individually. @@ -53,13 +53,11 @@ - + - - + + - - \ No newline at end of file diff --git a/src/DistributedLock/packages.lock.json b/src/DistributedLock/packages.lock.json new file mode 100644 index 0000000..b2d434b --- /dev/null +++ b/src/DistributedLock/packages.lock.json @@ -0,0 +1,1878 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.6.2": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.NETFramework.ReferenceAssemblies": { + "type": "Direct", + "requested": "[1.0.3, )", + "resolved": "1.0.3", + "contentHash": "vUc9Npcs14QsyOD01tnv/m8sQUnGTGOw1BCmKcv77LBJY7OxhJ+zJF7UD/sCL3lYNFuqmQEVlkfS4Quif6FyYg==", + "dependencies": { + "Microsoft.NETFramework.ReferenceAssemblies.net462": "1.0.3" + } + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.36.0", + "contentHash": "vwqFZdHS4dzPlI7FFRkPx9ctA+aGGeRev3gnzG8lntWvKMmBhAmulABi1O9CEvS3/jzYt7yA+0pqVdxkpAd7dQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Net.Http": "4.3.4", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.10.3", + "contentHash": "l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==", + "dependencies": { + "Azure.Core": "1.35.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.Identity.Client.Extensions.Msal": "4.56.0", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.7.0", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.18.1", + "contentHash": "ohCslqP9yDKIn+DVjBEOBuieB1QwsUCz+BwHYNaJ3lcIsTSiI4Evnq81HcKe8CqM8qvdModbipVQKpnxpbdWqA==", + "dependencies": { + "Azure.Core": "1.36.0", + "System.IO.Hashing": "6.0.0" + } + }, + "Microsoft.Bcl.HashCode": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "MalY0Y/uM/LjXtHfX/26l2VtN4LDNZ2OE3aumNOHDLsT4fNYy2hiHXI4CXCqKpNUNm7iJ2brrc4J89UdaL56FA==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.Data.SqlClient.SNI": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "0p2KMVc8WSC5JWgO+OdhYJiRM41dp6w2Dsd9JfEiHLPc6nyxBQgSrx9TYlbC8fRT2RK+HyWzDlv9ofFtxMOwQg==" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.22.0" + } + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==", + "dependencies": { + "Microsoft.Identity.Client": "4.56.0", + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "6.35.0", + "System.IdentityModel.Tokens.Jwt": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.NETFramework.ReferenceAssemblies.net462": { + "type": "Transitive", + "resolved": "1.0.3", + "contentHash": "IzAV30z22ESCeQfxP29oVf4qEo8fBGXLXSU6oacv/9Iqe6PzgHDKCaWfwMBak7bSJQM0F5boXWoZS+kChztRIQ==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Pipelines.Sockets.Unofficial": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "dependencies": { + "System.IO.Pipelines": "5.0.1" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "jXw9MlUu/kRfEU0WyTptAVueupqIeE3/rl0EZDMlf8pcvJnitQ8HeVEp69rZdaStXwTV72boi/Bhw8lOeO+U2w==", + "dependencies": { + "System.Security.Permissions": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Formats.Asn1": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "+nfpV0afLmvJW8+pLlHxRjz3oZJw4fkyU9MMEaMhCsHi/SN9bGF9q79ROubDiwTiCHezmK0uCWkPP7tGFP/4yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.ValueTuple": "4.5.0" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "System.IO.Compression": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==" + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Rfm2jYCaUeGysFEZjDe7j1R4x6Z6BzumS/vUT5a1AA/AWJuGX71PoGB0RmpyX3VmrGqVnAwtfMn39OHR8Y/5+g==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "5.0.1", + "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Net.Http": { + "type": "Transitive", + "resolved": "4.3.4", + "contentHash": "aOa2d51SEbmM+H+Csw7yJOuNZoHkrP2XnAurye5HWYgGVVU54YZDvsLUYRv6h18X3sPnjNCANmN7ZhIPiqMcjA==", + "dependencies": { + "System.Security.Cryptography.X509Certificates": "4.3.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Runtime.InteropServices.RuntimeInformation": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Cryptography.Algorithms": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "W1kd2Y8mYSCgc3ULTAZ0hOP2dSdG5YauTb1089T0/kRcN2MpSAW1izOFROrJgxSlMn3ArsgHXagigyi+ibhevg==", + "dependencies": { + "System.Security.Cryptography.Primitives": "4.3.0" + } + }, + "System.Security.Cryptography.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "1DEWjZZly9ae9C79vFwqaO5kaOlI5q+3/55ohmq/7dpDyDfc8lYe7YVxJUZ5MF/NtbkRjwFRo14yM4OEo9EmDw==" + }, + "System.Security.Cryptography.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "7bDIyVFNL/xKeFHjhobUAQqSpJq9YTOpbEs6mR233Et01STBMXNAc/V+BM6dwYGc95gVh/Zf+iVXWzj3mE8DWg==" + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "ehYW0m9ptxpGWvE4zgqongBVWpSDU/JCFD4K7krxkQwSz/sFQjEXCUqpvencjy6DYDbn7Ig09R8GFffu8TtneQ==" + }, + "System.Security.Cryptography.X509Certificates": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "t2Tmu6Y2NtJ2um0RtcuhP7ZdNNxXEgUm2JeoA/0NvlMjAhKCnM1NX07TDl3244mVp3QU6LPEhT3HTtH1uF7IYw==", + "dependencies": { + "System.Security.Cryptography.Algorithms": "4.3.0", + "System.Security.Cryptography.Encoding": "4.3.0" + } + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4", + "System.ValueTuple": "4.5.0" + } + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.azure": { + "type": "Project", + "dependencies": { + "Azure.Storage.Blobs": "[12.19.1, )", + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "distributedlock.filesystem": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.mysql": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "MySqlConnector": "[2.3.5, )" + } + }, + "distributedlock.oracle": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Oracle.ManagedDataAccess": "[21.13.0, )" + } + }, + "distributedlock.postgres": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Npgsql": "[8.0.2, )" + } + }, + "distributedlock.redis": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "StackExchange.Redis": "[2.7.27, )" + } + }, + "distributedlock.sqlserver": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Microsoft.Data.SqlClient": "[5.2.0, )" + } + }, + "distributedlock.waithandles": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.zookeeper": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "ZooKeeperNetEx": "[3.4.12.4, )" + } + }, + "Azure.Storage.Blobs": { + "type": "CentralTransitive", + "requested": "[12.19.1, )", + "resolved": "12.19.1", + "contentHash": "x43hWFJ4sPQ23TD4piCwT+KlQpZT8pNDAzqj6yUCqh+WJ2qcQa17e1gh6ZOeT2QNFQTTDSuR56fm2bIV7i11/w==", + "dependencies": { + "Azure.Storage.Common": "12.18.1", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Data.SqlClient": { + "type": "CentralTransitive", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "System.Buffers": "4.5.1", + "System.Configuration.ConfigurationManager": "6.0.1", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Text.Encodings.Web": "6.0.0" + } + }, + "MySqlConnector": { + "type": "CentralTransitive", + "requested": "[2.3.5, )", + "resolved": "2.3.5", + "contentHash": "AmEfUPkFl+Ev6jJ8Dhns3CYHBfD12RHzGYWuLt6DfG6/af6YvOMyPz74ZPPjBYQGRJkumD2Z48Kqm8s5DJuhLA==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "7.0.1", + "System.Diagnostics.DiagnosticSource": "7.0.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Npgsql": { + "type": "CentralTransitive", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "MuJzLoWCaQhQAR3oh66YR0Ir6mxuezncGX3f8wxvAc21g0+9HICktJQlqMoODhxztZKXE5k9GxRxqUAN+vPb4g==", + "dependencies": { + "Microsoft.Bcl.HashCode": "1.1.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "System.Collections.Immutable": "8.0.0", + "System.Diagnostics.DiagnosticSource": "8.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Json": "8.0.0", + "System.Threading.Channels": "8.0.0" + } + }, + "Oracle.ManagedDataAccess": { + "type": "CentralTransitive", + "requested": "[21.13.0, )", + "resolved": "21.13.0", + "contentHash": "3OaqQzmx5aRrjBfPu44BaGy9Jz+NiO8Q7x+jPrSL91nSc/M4JYv6j/aX1dwdq4rlSHAw6Ct9rUsd0z7xjvq0Gw==", + "dependencies": { + "System.Formats.Asn1": "7.0.0", + "System.Text.Json": "6.0.1" + } + }, + "StackExchange.Redis": { + "type": "CentralTransitive", + "requested": "[2.7.27, )", + "resolved": "2.7.27", + "contentHash": "Uqc2OQHglqj9/FfGQ6RkKFkZfHySfZlfmbCl+hc+u2I/IqunfelQ7QJi7ZhvAJxUtu80pildVX6NPLdDaUffOw==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "5.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8", + "System.IO.Compression": "4.3.0", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Threading.Channels": "5.0.0" + } + }, + "System.ValueTuple": { + "type": "CentralTransitive", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + }, + "ZooKeeperNetEx": { + "type": "CentralTransitive", + "requested": "[3.4.12.4, )", + "resolved": "3.4.12.4", + "contentHash": "YECtByVSH7TRjQKplwOWiKyanCqYE5eEkGk5YtHJgsnbZ6+p1o0Gvs5RIsZLotiAVa6Niez1BJyKY/RDY/L6zg==" + } + }, + ".NETStandard,Version=v2.0": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "NETStandard.Library": { + "type": "Direct", + "requested": "[2.0.3, )", + "resolved": "2.0.3", + "contentHash": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.36.0", + "contentHash": "vwqFZdHS4dzPlI7FFRkPx9ctA+aGGeRev3gnzG8lntWvKMmBhAmulABi1O9CEvS3/jzYt7yA+0pqVdxkpAd7dQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.10.3", + "contentHash": "l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==", + "dependencies": { + "Azure.Core": "1.35.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.Identity.Client.Extensions.Msal": "4.56.0", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.7.0", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.18.1", + "contentHash": "ohCslqP9yDKIn+DVjBEOBuieB1QwsUCz+BwHYNaJ3lcIsTSiI4Evnq81HcKe8CqM8qvdModbipVQKpnxpbdWqA==", + "dependencies": { + "Azure.Core": "1.36.0", + "System.IO.Hashing": "6.0.0" + } + }, + "Microsoft.Bcl.HashCode": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "MalY0Y/uM/LjXtHfX/26l2VtN4LDNZ2OE3aumNOHDLsT4fNYy2hiHXI4CXCqKpNUNm7iJ2brrc4J89UdaL56FA==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CSharp": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "kaj6Wb4qoMuH3HySFJhxwQfe8R/sJsNJnANrvv8WdFPMoNbKY5htfNscv+LHCu5ipz+49m2e+WQXpLXr9XYemQ==" + }, + "Microsoft.Data.SqlClient.SNI.runtime": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "po1jhvFd+8pbfvJR/puh+fkHi0GRanAdvayh/0e47yaM6CXWZ6opUjCMFuYlAnD2LcbyvQE7fPJKvogmaUcN+w==" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.22.0" + } + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==", + "dependencies": { + "Microsoft.Identity.Client": "4.56.0", + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "6.35.0", + "System.IdentityModel.Tokens.Jwt": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==", + "dependencies": { + "Microsoft.CSharp": "4.5.0", + "Microsoft.IdentityModel.Logging": "6.35.0", + "System.Security.Cryptography.Cng": "4.5.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Microsoft.SqlServer.Server": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "N4KeF3cpcm1PUHym1RmakkzfkEv3GRMyofVv40uXsQhCQeglr2OHNcUk2WOG51AKpGO8ynGpo9M/kFXSzghwug==" + }, + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "Pipelines.Sockets.Unofficial": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "dependencies": { + "System.IO.Pipelines": "5.0.1" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "jXw9MlUu/kRfEU0WyTptAVueupqIeE3/rl0EZDMlf8pcvJnitQ8HeVEp69rZdaStXwTV72boi/Bhw8lOeO+U2w==", + "dependencies": { + "System.Security.Cryptography.ProtectedData": "6.0.0", + "System.Security.Permissions": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "System.IO": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Rfm2jYCaUeGysFEZjDe7j1R4x6Z6BzumS/vUT5a1AA/AWJuGX71PoGB0RmpyX3VmrGqVnAwtfMn39OHR8Y/5+g==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "5.0.1", + "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Reflection": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "System.Runtime.Caching": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "E0e03kUp5X2k+UAoVl6efmI7uU7JRBWi5EIdlQ7cr0NpBGjHG4fWII35PgsBY9T4fJQ8E4QPsL0rKksU9gcL5A==", + "dependencies": { + "System.Configuration.ConfigurationManager": "6.0.0" + } + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Runtime.Loader": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "DHMaRn8D8YCK2GG2pw+UzNxn/OHVfaWx7OTLBD/hPegHZZgcZh3H6seWegrC4BYwsfuGrywIuT+MQs+rPqRLTQ==", + "dependencies": { + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Cryptography.Cng": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "jIMXsKn94T9JY7PvPq/tMfqa6GAaHpElRDpmG+SuL+D3+sTw2M8VhnibKnN8Tq+4JqbPJ/f+BwtLeDMEnzAvRg==" + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ==", + "dependencies": { + "System.Memory": "4.5.4" + } + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.azure": { + "type": "Project", + "dependencies": { + "Azure.Storage.Blobs": "[12.19.1, )", + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )" + } + }, + "distributedlock.filesystem": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.mysql": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "MySqlConnector": "[2.3.5, )" + } + }, + "distributedlock.postgres": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Npgsql": "[8.0.2, )" + } + }, + "distributedlock.redis": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "StackExchange.Redis": "[2.7.27, )" + } + }, + "distributedlock.sqlserver": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Microsoft.Data.SqlClient": "[5.2.0, )" + } + }, + "distributedlock.waithandles": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "System.Threading.AccessControl": "[8.0.0, )" + } + }, + "distributedlock.zookeeper": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "ZooKeeperNetEx": "[3.4.12.4, )" + } + }, + "Azure.Storage.Blobs": { + "type": "CentralTransitive", + "requested": "[12.19.1, )", + "resolved": "12.19.1", + "contentHash": "x43hWFJ4sPQ23TD4piCwT+KlQpZT8pNDAzqj6yUCqh+WJ2qcQa17e1gh6ZOeT2QNFQTTDSuR56fm2bIV7i11/w==", + "dependencies": { + "Azure.Storage.Common": "12.18.1", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Data.SqlClient": { + "type": "CentralTransitive", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI.runtime": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "Microsoft.SqlServer.Server": "1.0.0", + "Microsoft.Win32.Registry": "5.0.0", + "System.Buffers": "4.5.1", + "System.Configuration.ConfigurationManager": "6.0.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Runtime.Caching": "6.0.0", + "System.Runtime.Loader": "4.3.0", + "System.Security.Cryptography.Cng": "5.0.0", + "System.Security.Principal.Windows": "5.0.0", + "System.Text.Encoding.CodePages": "6.0.0", + "System.Text.Encodings.Web": "6.0.0" + } + }, + "MySqlConnector": { + "type": "CentralTransitive", + "requested": "[2.3.5, )", + "resolved": "2.3.5", + "contentHash": "AmEfUPkFl+Ev6jJ8Dhns3CYHBfD12RHzGYWuLt6DfG6/af6YvOMyPz74ZPPjBYQGRJkumD2Z48Kqm8s5DJuhLA==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "7.0.1", + "System.Diagnostics.DiagnosticSource": "7.0.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Npgsql": { + "type": "CentralTransitive", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "MuJzLoWCaQhQAR3oh66YR0Ir6mxuezncGX3f8wxvAc21g0+9HICktJQlqMoODhxztZKXE5k9GxRxqUAN+vPb4g==", + "dependencies": { + "Microsoft.Bcl.HashCode": "1.1.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "System.Collections.Immutable": "8.0.0", + "System.Diagnostics.DiagnosticSource": "8.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Json": "8.0.0", + "System.Threading.Channels": "8.0.0" + } + }, + "StackExchange.Redis": { + "type": "CentralTransitive", + "requested": "[2.7.27, )", + "resolved": "2.7.27", + "contentHash": "Uqc2OQHglqj9/FfGQ6RkKFkZfHySfZlfmbCl+hc+u2I/IqunfelQ7QJi7ZhvAJxUtu80pildVX6NPLdDaUffOw==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "5.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8", + "System.Threading.Channels": "5.0.0" + } + }, + "System.Threading.AccessControl": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Security.AccessControl": "6.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "ZooKeeperNetEx": { + "type": "CentralTransitive", + "requested": "[3.4.12.4, )", + "resolved": "3.4.12.4", + "contentHash": "YECtByVSH7TRjQKplwOWiKyanCqYE5eEkGk5YtHJgsnbZ6+p1o0Gvs5RIsZLotiAVa6Niez1BJyKY/RDY/L6zg==" + } + }, + ".NETStandard,Version=v2.1": { + "Microsoft.CodeAnalysis.PublicApiAnalyzers": { + "type": "Direct", + "requested": "[3.3.4, )", + "resolved": "3.3.4", + "contentHash": "kNLTfXtXUWDHVt5iaPkkiPuyHYlMgLI6SOFT4w88bfeI2vqSeGgHunFkdvlaCM8RDfcY0t2+jnesQtidRJJ/DA==" + }, + "Microsoft.SourceLink.GitHub": { + "type": "Direct", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "G5q7OqtwIyGTkeIOAc3u2ZuV/kicQaec5EaRnc0pIeSnh9LUjj+PYQrJYBURvDt7twGl2PKA7nSN0kz1Zw5bnQ==", + "dependencies": { + "Microsoft.Build.Tasks.Git": "8.0.0", + "Microsoft.SourceLink.Common": "8.0.0" + } + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.36.0", + "contentHash": "vwqFZdHS4dzPlI7FFRkPx9ctA+aGGeRev3gnzG8lntWvKMmBhAmulABi1O9CEvS3/jzYt7yA+0pqVdxkpAd7dQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.10.3", + "contentHash": "l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==", + "dependencies": { + "Azure.Core": "1.35.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.Identity.Client.Extensions.Msal": "4.56.0", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.7.0", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.18.1", + "contentHash": "ohCslqP9yDKIn+DVjBEOBuieB1QwsUCz+BwHYNaJ3lcIsTSiI4Evnq81HcKe8CqM8qvdModbipVQKpnxpbdWqA==", + "dependencies": { + "Azure.Core": "1.36.0", + "System.IO.Hashing": "6.0.0" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==" + }, + "Microsoft.Build.Tasks.Git": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "bZKfSIKJRXLTuSzLudMFte/8CempWjVamNUR5eHJizsy+iuOuO/k2gnh7W0dHJmYY0tBf+gUErfluCv5mySAOQ==" + }, + "Microsoft.CSharp": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "kaj6Wb4qoMuH3HySFJhxwQfe8R/sJsNJnANrvv8WdFPMoNbKY5htfNscv+LHCu5ipz+49m2e+WQXpLXr9XYemQ==" + }, + "Microsoft.Data.SqlClient.SNI.runtime": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "po1jhvFd+8pbfvJR/puh+fkHi0GRanAdvayh/0e47yaM6CXWZ6opUjCMFuYlAnD2LcbyvQE7fPJKvogmaUcN+w==" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.22.0" + } + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==", + "dependencies": { + "Microsoft.Identity.Client": "4.56.0", + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "6.35.0", + "System.IdentityModel.Tokens.Jwt": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==", + "dependencies": { + "Microsoft.CSharp": "4.5.0", + "Microsoft.IdentityModel.Logging": "6.35.0", + "System.Security.Cryptography.Cng": "4.5.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, + "Microsoft.SourceLink.Common": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "dk9JPxTCIevS75HyEQ0E4OVAFhB2N+V9ShCXf8Q6FkUQZDkgLI12y679Nym1YqsiSysuQskT7Z+6nUf3yab6Vw==" + }, + "Microsoft.SqlServer.Server": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "N4KeF3cpcm1PUHym1RmakkzfkEv3GRMyofVv40uXsQhCQeglr2OHNcUk2WOG51AKpGO8ynGpo9M/kFXSzghwug==" + }, + "Microsoft.Win32.Registry": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "dDoKi0PnDz31yAyETfRntsLArTlVAVzUzCIvvEDsDsucrl33Dl8pIJG06ePTJTI3tGpeyHS9Cq7Foc/s4EeKcg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "Pipelines.Sockets.Unofficial": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "dependencies": { + "System.IO.Pipelines": "5.0.1" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "jXw9MlUu/kRfEU0WyTptAVueupqIeE3/rl0EZDMlf8pcvJnitQ8HeVEp69rZdaStXwTV72boi/Bhw8lOeO+U2w==", + "dependencies": { + "System.Security.Cryptography.ProtectedData": "6.0.0", + "System.Security.Permissions": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Diagnostics.PerformanceCounter": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "dDl7Gx3bmSrM2k2ZIm+ucEJnLloZRyvfQF1DvfvATcGF3jtaUBiPvChma+6ZcZzxWMirN3kCywkW7PILphXyMQ==" + }, + "System.DirectoryServices": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "935IbO7h5FDGYxeO3cbx/CuvBBuk/VI8sENlfmXlh1pupNOB3LAGzdYdPY8CawGJFP7KNrHK5eUlsFoz3F6cuA==", + "dependencies": { + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.AccessControl": "6.0.0", + "System.Security.Permissions": "6.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.DirectoryServices.Protocols": { + "type": "Transitive", + "resolved": "6.0.2", + "contentHash": "vDDPWwHn3/DNZ+kPkdXHoada+tKPEC9bVqDOr4hK6HBSP7hGCUTA0Zw6WU5qpGaqa5M1/V+axHMIv+DNEbIf6g==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "System.IO": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "3qjaHvxQPDpSOYICjUoTsmoq5u6QJAFRUITgeT/4gqkF1bajbSmb1kwSxEA8AHlofqgcKJcM8udgieRNhaJ5Cg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "System.Text.Encoding": "4.3.0", + "System.Threading.Tasks": "4.3.0" + } + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Rfm2jYCaUeGysFEZjDe7j1R4x6Z6BzumS/vUT5a1AA/AWJuGX71PoGB0RmpyX3VmrGqVnAwtfMn39OHR8Y/5+g==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "5.0.1", + "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.4.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Reflection": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "KMiAFoW7MfJGa9nDFNcfu+FpEdiHpWgTcS2HdMpDvt9saK3y/G4GwprPyzqjFH9NTaGPQeWNHU+iDlDILj96aQ==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.IO": "4.3.0", + "System.Reflection.Primitives": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Reflection.Primitives": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "5RXItQz5As4xN2/YUDxdpsEkMhvw3e6aNveFXUn4Hl/udNTCNhnKp8lT9fnc3MhvGKh1baak5CovpuQUXHAlIA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "System.Runtime.Caching": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "E0e03kUp5X2k+UAoVl6efmI7uU7JRBWi5EIdlQ7cr0NpBGjHG4fWII35PgsBY9T4fJQ8E4QPsL0rKksU9gcL5A==", + "dependencies": { + "System.Configuration.ConfigurationManager": "6.0.0" + } + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Runtime.Loader": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "DHMaRn8D8YCK2GG2pw+UzNxn/OHVfaWx7OTLBD/hPegHZZgcZh3H6seWegrC4BYwsfuGrywIuT+MQs+rPqRLTQ==", + "dependencies": { + "System.IO": "4.3.0", + "System.Reflection": "4.3.0", + "System.Runtime": "4.3.0" + } + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Cryptography.Cng": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "jIMXsKn94T9JY7PvPq/tMfqa6GAaHpElRDpmG+SuL+D3+sTw2M8VhnibKnN8Tq+4JqbPJ/f+BwtLeDMEnzAvRg==" + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "rp1gMNEZpvx9vP0JW0oHLxlf8oSiQgtno77Y4PLUBjSiDYoD77Y8uXHr1Ea5XG4/pIKhqAdxZ8v8OTUtqo9PeQ==", + "dependencies": { + "System.Memory": "4.5.4" + } + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Text.Encoding.CodePages": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "ZFCILZuOvtKPauZ/j/swhvw68ZRi9ATCfvGbk1QfydmcXBkIWecWKn/250UH7rahZ5OoDBaiAudJtPvLwzw85A==", + "dependencies": { + "System.Memory": "4.5.4", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==" + }, + "System.Threading.Tasks": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "LbSxKEdOUhVe8BezB/9uOGGppt+nZf6e1VFyw6v3DN6lqitm0OSn2uXMOdtP0M3W4iMcqcivm2J6UgqiwwnXiA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "distributedlock.azure": { + "type": "Project", + "dependencies": { + "Azure.Storage.Blobs": "[12.19.1, )", + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.core": { + "type": "Project" + }, + "distributedlock.filesystem": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.mysql": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "MySqlConnector": "[2.3.5, )" + } + }, + "distributedlock.oracle": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Oracle.ManagedDataAccess.Core": "[3.21.130, )" + } + }, + "distributedlock.postgres": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Npgsql": "[8.0.2, )" + } + }, + "distributedlock.redis": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "StackExchange.Redis": "[2.7.27, )" + } + }, + "distributedlock.sqlserver": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Microsoft.Data.SqlClient": "[5.2.0, )" + } + }, + "distributedlock.waithandles": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "System.Threading.AccessControl": "[8.0.0, )" + } + }, + "distributedlock.zookeeper": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "ZooKeeperNetEx": "[3.4.12.4, )" + } + }, + "Azure.Storage.Blobs": { + "type": "CentralTransitive", + "requested": "[12.19.1, )", + "resolved": "12.19.1", + "contentHash": "x43hWFJ4sPQ23TD4piCwT+KlQpZT8pNDAzqj6yUCqh+WJ2qcQa17e1gh6ZOeT2QNFQTTDSuR56fm2bIV7i11/w==", + "dependencies": { + "Azure.Storage.Common": "12.18.1", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.Data.SqlClient": { + "type": "CentralTransitive", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI.runtime": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "Microsoft.SqlServer.Server": "1.0.0", + "Microsoft.Win32.Registry": "5.0.0", + "System.Configuration.ConfigurationManager": "6.0.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Runtime.Caching": "6.0.0", + "System.Runtime.Loader": "4.3.0", + "System.Security.Cryptography.Cng": "5.0.0", + "System.Security.Principal.Windows": "5.0.0", + "System.Text.Encoding.CodePages": "6.0.0", + "System.Text.Encodings.Web": "6.0.0" + } + }, + "MySqlConnector": { + "type": "CentralTransitive", + "requested": "[2.3.5, )", + "resolved": "2.3.5", + "contentHash": "AmEfUPkFl+Ev6jJ8Dhns3CYHBfD12RHzGYWuLt6DfG6/af6YvOMyPz74ZPPjBYQGRJkumD2Z48Kqm8s5DJuhLA==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "7.0.1", + "System.Diagnostics.DiagnosticSource": "7.0.2" + } + }, + "Npgsql": { + "type": "CentralTransitive", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "MuJzLoWCaQhQAR3oh66YR0Ir6mxuezncGX3f8wxvAc21g0+9HICktJQlqMoODhxztZKXE5k9GxRxqUAN+vPb4g==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "System.Collections.Immutable": "8.0.0", + "System.Diagnostics.DiagnosticSource": "8.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Json": "8.0.0", + "System.Threading.Channels": "8.0.0" + } + }, + "Oracle.ManagedDataAccess.Core": { + "type": "CentralTransitive", + "requested": "[3.21.130, )", + "resolved": "3.21.130", + "contentHash": "bXNwPyAaDivO84HEYiegK7r/LleSEfA0nc70bE88wkqd1E0Q1+r/SUbJ51xOK2vk6iHbTSMuhnC79BU8svPBjQ==", + "dependencies": { + "System.Diagnostics.PerformanceCounter": "6.0.1", + "System.DirectoryServices": "6.0.1", + "System.DirectoryServices.Protocols": "6.0.2", + "System.Text.Json": "6.0.1" + } + }, + "StackExchange.Redis": { + "type": "CentralTransitive", + "requested": "[2.7.27, )", + "resolved": "2.7.27", + "contentHash": "Uqc2OQHglqj9/FfGQ6RkKFkZfHySfZlfmbCl+hc+u2I/IqunfelQ7QJi7ZhvAJxUtu80pildVX6NPLdDaUffOw==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "5.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8", + "System.Threading.Channels": "5.0.0" + } + }, + "System.Threading.AccessControl": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Security.AccessControl": "6.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "ZooKeeperNetEx": { + "type": "CentralTransitive", + "requested": "[3.4.12.4, )", + "resolved": "3.4.12.4", + "contentHash": "YECtByVSH7TRjQKplwOWiKyanCqYE5eEkGk5YtHJgsnbZ6+p1o0Gvs5RIsZLotiAVa6Niez1BJyKY/RDY/L6zg==" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLockCodeGen/CodeGenHelpers.cs b/src/DistributedLockCodeGen/CodeGenHelpers.cs index c73d419..80da686 100644 --- a/src/DistributedLockCodeGen/CodeGenHelpers.cs +++ b/src/DistributedLockCodeGen/CodeGenHelpers.cs @@ -13,8 +13,8 @@ internal static class CodeGenHelpers public static IEnumerable EnumerateSolutionFiles() => Directory.EnumerateFiles(SolutionDirectory, "*.csproj", SearchOption.AllDirectories) .Select(Path.GetDirectoryName) - .Where(d => !Regex.IsMatch(Path.GetFileName(d), "^(DistributedLock|DistributedLock.Tests|DistributedLockCodeGen)$", RegexOptions.IgnoreCase)) - .SelectMany(d => Directory.EnumerateFiles(d, "*.cs", SearchOption.AllDirectories)); + .Where(d => !Regex.IsMatch(Path.GetFileName(d)!, "^(DistributedLock|DistributedLock.Tests|DistributedLockCodeGen)$", RegexOptions.IgnoreCase)) + .SelectMany(d => Directory.EnumerateFiles(d!, "*.cs", SearchOption.AllDirectories)); public static string NormalizeCodeWhitespace(string code) => code.Trim().Replace("\r\n", "\n"); diff --git a/src/DistributedLockCodeGen/DistributedLockCodeGen.csproj b/src/DistributedLockCodeGen/DistributedLockCodeGen.csproj index 9a1d455..2cda37e 100644 --- a/src/DistributedLockCodeGen/DistributedLockCodeGen.csproj +++ b/src/DistributedLockCodeGen/DistributedLockCodeGen.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1 + net8.0 Latest false enable @@ -10,9 +10,9 @@ - - - + + + diff --git a/src/DistributedLockCodeGen/packages.lock.json b/src/DistributedLockCodeGen/packages.lock.json new file mode 100644 index 0000000..3fd1f68 --- /dev/null +++ b/src/DistributedLockCodeGen/packages.lock.json @@ -0,0 +1,77 @@ +{ + "version": 2, + "dependencies": { + "net8.0": { + "Microsoft.NET.Test.Sdk": { + "type": "Direct", + "requested": "[17.9.0, )", + "resolved": "17.9.0", + "contentHash": "7GUNAUbJYn644jzwLm5BD3a2p9C1dmP8Hr6fDPDxgItQk9hBs1Svdxzz07KQ/UphMSmgza9AbijBJGmw5D658A==", + "dependencies": { + "Microsoft.CodeCoverage": "17.9.0", + "Microsoft.TestPlatform.TestHost": "17.9.0" + } + }, + "NUnit": { + "type": "Direct", + "requested": "[3.14.0, )", + "resolved": "3.14.0", + "contentHash": "R7iPwD7kbOaP3o2zldWJbWeMQAvDKD0uld27QvA3PAALl1unl7x0v2J7eGiJOYjimV/BuGT4VJmr45RjS7z4LA==", + "dependencies": { + "NETStandard.Library": "2.0.0" + } + }, + "NUnit3TestAdapter": { + "type": "Direct", + "requested": "[4.5.0, )", + "resolved": "4.5.0", + "contentHash": "s8JpqTe9bI2f49Pfr3dFRfoVSuFQyraTj68c3XXjIS/MRGvvkLnrg6RLqnTjdShX+AdFUCCU/4Xex58AdUfs6A==" + }, + "Microsoft.CodeCoverage": { + "type": "Transitive", + "resolved": "17.9.0", + "contentHash": "RGD37ZSrratfScYXm7M0HjvxMxZyWZL4jm+XgMZbkIY1UPgjUpbNA/t+WTGj/rC/0Hm9A3IrH3ywbKZkOCnoZA==" + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.TestPlatform.ObjectModel": { + "type": "Transitive", + "resolved": "17.9.0", + "contentHash": "1ilw/8vgmjLyKU+2SKXKXaOqpYFJCQfGqGz+x0cosl981VzjrY74Sv6qAJv+neZMZ9ZMxF3ArN6kotaQ4uvEBw==", + "dependencies": { + "System.Reflection.Metadata": "1.6.0" + } + }, + "Microsoft.TestPlatform.TestHost": { + "type": "Transitive", + "resolved": "17.9.0", + "contentHash": "Spmg7Wx49Ya3SxBjyeAR+nQpjMTKZwTwpZ7KyeOTIqI/WHNPnBU4HUvl5kuHPQAwGWqMy4FGZja1HvEwvoaDiA==", + "dependencies": { + "Microsoft.TestPlatform.ObjectModel": "17.9.0", + "Newtonsoft.Json": "13.0.1" + } + }, + "NETStandard.Library": { + "type": "Transitive", + "resolved": "2.0.0", + "contentHash": "7jnbRU+L08FXKMxqUflxEXtVymWvNOrS8yHgu9s6EM8Anr6T/wIX4nZ08j/u3Asz+tCufp3YVwFSEvFTPYmBPA==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Newtonsoft.Json": { + "type": "Transitive", + "resolved": "13.0.1", + "contentHash": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==" + }, + "System.Reflection.Metadata": { + "type": "Transitive", + "resolved": "1.6.0", + "contentHash": "COC1aiAJjCoA5GBF+QKL2uLqEBew4JsCkQmoHKbN3TlOZKa2fKLz5CpiRQKDz0RsAOEGsVKqOD5bomsXq/4STQ==" + } + } + } +} \ No newline at end of file diff --git a/src/DistributedLockTaker/DistributedLockTaker.csproj b/src/DistributedLockTaker/DistributedLockTaker.csproj index 37cf833..d7197b2 100644 --- a/src/DistributedLockTaker/DistributedLockTaker.csproj +++ b/src/DistributedLockTaker/DistributedLockTaker.csproj @@ -1,7 +1,7 @@  - net471;netcoreapp3.1 + net472;net8.0 Exe false Latest diff --git a/src/DistributedLockTaker/Program.cs b/src/DistributedLockTaker/Program.cs index e42414d..c15d0a5 100644 --- a/src/DistributedLockTaker/Program.cs +++ b/src/DistributedLockTaker/Program.cs @@ -15,11 +15,6 @@ using Medallion.Threading.ZooKeeper; using Medallion.Threading.MySql; using Medallion.Threading.Oracle; -#if NET471 -using System.Data.SqlClient; -#elif NETCOREAPP3_1 -using Microsoft.Data.SqlClient; -#endif namespace DistributedLockTaker; diff --git a/src/DistributedLockTaker/packages.lock.json b/src/DistributedLockTaker/packages.lock.json new file mode 100644 index 0000000..bc71945 --- /dev/null +++ b/src/DistributedLockTaker/packages.lock.json @@ -0,0 +1,1258 @@ +{ + "version": 2, + "dependencies": { + ".NETFramework,Version=v4.7.2": { + "Azure.Core": { + "type": "Transitive", + "resolved": "1.36.0", + "contentHash": "vwqFZdHS4dzPlI7FFRkPx9ctA+aGGeRev3gnzG8lntWvKMmBhAmulABi1O9CEvS3/jzYt7yA+0pqVdxkpAd7dQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.10.3", + "contentHash": "l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==", + "dependencies": { + "Azure.Core": "1.35.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.Identity.Client.Extensions.Msal": "4.56.0", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.7.0", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.18.1", + "contentHash": "ohCslqP9yDKIn+DVjBEOBuieB1QwsUCz+BwHYNaJ3lcIsTSiI4Evnq81HcKe8CqM8qvdModbipVQKpnxpbdWqA==", + "dependencies": { + "Azure.Core": "1.36.0", + "System.IO.Hashing": "6.0.0" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "3WA9q9yVqJp222P3x1wYIGDAkpjAku0TMUaaQV22g6L67AI0LdOIrVS7Ht2vJfLHGSPVuqN94vIr15qn+HEkHw==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Bcl.HashCode": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "MalY0Y/uM/LjXtHfX/26l2VtN4LDNZ2OE3aumNOHDLsT4fNYy2hiHXI4CXCqKpNUNm7iJ2brrc4J89UdaL56FA==" + }, + "Microsoft.Data.SqlClient.SNI": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "0p2KMVc8WSC5JWgO+OdhYJiRM41dp6w2Dsd9JfEiHLPc6nyxBQgSrx9TYlbC8fRT2RK+HyWzDlv9ofFtxMOwQg==" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5" + } + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.22.0" + } + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==", + "dependencies": { + "Microsoft.Identity.Client": "4.56.0", + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "6.35.0", + "System.IdentityModel.Tokens.Jwt": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Oracle.ManagedDataAccess": { + "type": "Transitive", + "resolved": "21.13.0", + "contentHash": "3OaqQzmx5aRrjBfPu44BaGy9Jz+NiO8Q7x+jPrSL91nSc/M4JYv6j/aX1dwdq4rlSHAw6Ct9rUsd0z7xjvq0Gw==", + "dependencies": { + "System.Formats.Asn1": "7.0.0", + "System.Text.Json": "6.0.1" + } + }, + "Pipelines.Sockets.Unofficial": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "dependencies": { + "System.IO.Pipelines": "5.0.1" + } + }, + "System.Buffers": { + "type": "Transitive", + "resolved": "4.5.1", + "contentHash": "Rw7ijyl1qqRS0YQD/WycNst8hUUMgrMH4FCn1nNm27M4VxchZ1js3fVjQaANHO5f3sN4isvP4a+Met9Y4YomAg==" + }, + "System.Collections.Immutable": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "AurL6Y5BA1WotzlEvVaIDpqzpIPvYnnldxru8oXJU2yFxFUy3+pNXjXd1ymO+RA0rq0+590Q8gaz2l3Sr7fmqg==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "jXw9MlUu/kRfEU0WyTptAVueupqIeE3/rl0EZDMlf8pcvJnitQ8HeVEp69rZdaStXwTV72boi/Bhw8lOeO+U2w==", + "dependencies": { + "System.Security.Permissions": "6.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "c9xLpVz6PL9lp/djOWtk5KPDZq3cSYpmXoJQY524EOtuFl5z9ZtsotpsyrDW40U1DRnQSYvcPKEUV0X//u6gkQ==", + "dependencies": { + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Formats.Asn1": { + "type": "Transitive", + "resolved": "7.0.0", + "contentHash": "+nfpV0afLmvJW8+pLlHxRjz3oZJw4fkyU9MMEaMhCsHi/SN9bGF9q79ROubDiwTiCHezmK0uCWkPP7tGFP/4yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.ValueTuple": "4.5.0" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "System.IO.Compression": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==" + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Rfm2jYCaUeGysFEZjDe7j1R4x6Z6BzumS/vUT5a1AA/AWJuGX71PoGB0RmpyX3VmrGqVnAwtfMn39OHR8Y/5+g==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4" + } + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "5.0.1", + "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.4", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.5", + "contentHash": "XIWiDvKPXaTveaB7HVganDlOCRoj03l+jrwNvcge/t8vhGYKvqV+dMv6G4SAX2NoNmN0wZfVPTAlFwZcZvVOUw==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Numerics.Vectors": "4.5.0", + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Runtime.InteropServices.RuntimeInformation": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "ehYW0m9ptxpGWvE4zgqongBVWpSDU/JCFD4K7krxkQwSz/sFQjEXCUqpvencjy6DYDbn7Ig09R8GFffu8TtneQ==" + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==" + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "yev/k9GHAEGx2Rg3/tU6MQh4HGBXJs70y7j1LaM1i/ER9po+6nnQ6RRqTJn1E7Xu0fbIFK80Nh5EoODxrbxwBQ==", + "dependencies": { + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "OdrZO2WjkiEG6ajEFRABTRCi/wuXQPxeV6g8xvUJqdxMvvuCCEk86zPla8UiIQJz3durtUEbNyY/3lIhS0yZvQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "8.0.0", + "System.Buffers": "4.5.1", + "System.Memory": "4.5.5", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Encodings.Web": "8.0.0", + "System.Threading.Tasks.Extensions": "4.5.4", + "System.ValueTuple": "4.5.0" + } + }, + "System.Threading.Channels": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "CMaFr7v+57RW7uZfZkPExsPB6ljwzhjACWW1gfU35Y56rk72B/Wu+sTqxVmGSk4SFUlPc3cjeKND0zktziyjBA==", + "dependencies": { + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "4.5.3" + } + }, + "System.ValueTuple": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "okurQJO6NRE/apDIP23ajJ0hpiNmJ+f0BwOlB/cSqTLQlw5upkf+5+96+iG2Jw40G1fCVCyPz/FhIABUjMR+RQ==" + }, + "distributedlock": { + "type": "Project", + "dependencies": { + "DistributedLock.Azure": "[1.0.1, )", + "DistributedLock.FileSystem": "[1.0.2, )", + "DistributedLock.MySql": "[1.0.2, )", + "DistributedLock.Oracle": "[1.0.3, )", + "DistributedLock.Postgres": "[1.1.0, )", + "DistributedLock.Redis": "[1.0.3, )", + "DistributedLock.SqlServer": "[1.0.4, )", + "DistributedLock.WaitHandles": "[1.0.1, )", + "DistributedLock.ZooKeeper": "[1.0.0, )" + } + }, + "distributedlock.azure": { + "type": "Project", + "dependencies": { + "Azure.Storage.Blobs": "[12.19.1, )", + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.core": { + "type": "Project", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "[8.0.0, )", + "System.ValueTuple": "[4.5.0, )" + } + }, + "distributedlock.filesystem": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.mysql": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "MySqlConnector": "[2.3.5, )" + } + }, + "distributedlock.oracle": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Oracle.ManagedDataAccess": "[21.13.0, )" + } + }, + "distributedlock.postgres": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Npgsql": "[8.0.2, )" + } + }, + "distributedlock.redis": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "StackExchange.Redis": "[2.7.27, )" + } + }, + "distributedlock.sqlserver": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Microsoft.Data.SqlClient": "[5.2.0, )" + } + }, + "distributedlock.waithandles": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.zookeeper": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "ZooKeeperNetEx": "[3.4.12.4, )" + } + }, + "Azure.Storage.Blobs": { + "type": "CentralTransitive", + "requested": "[12.19.1, )", + "resolved": "12.19.1", + "contentHash": "x43hWFJ4sPQ23TD4piCwT+KlQpZT8pNDAzqj6yUCqh+WJ2qcQa17e1gh6ZOeT2QNFQTTDSuR56fm2bIV7i11/w==", + "dependencies": { + "Azure.Storage.Common": "12.18.1", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.Data.SqlClient": { + "type": "CentralTransitive", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "System.Buffers": "4.5.1", + "System.Configuration.ConfigurationManager": "6.0.1", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Text.Encodings.Web": "6.0.0" + } + }, + "MySqlConnector": { + "type": "CentralTransitive", + "requested": "[2.3.5, )", + "resolved": "2.3.5", + "contentHash": "AmEfUPkFl+Ev6jJ8Dhns3CYHBfD12RHzGYWuLt6DfG6/af6YvOMyPz74ZPPjBYQGRJkumD2Z48Kqm8s5DJuhLA==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "7.0.1", + "System.Diagnostics.DiagnosticSource": "7.0.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Npgsql": { + "type": "CentralTransitive", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "MuJzLoWCaQhQAR3oh66YR0Ir6mxuezncGX3f8wxvAc21g0+9HICktJQlqMoODhxztZKXE5k9GxRxqUAN+vPb4g==", + "dependencies": { + "Microsoft.Bcl.HashCode": "1.1.1", + "Microsoft.Extensions.Logging.Abstractions": "8.0.0", + "System.Collections.Immutable": "8.0.0", + "System.Diagnostics.DiagnosticSource": "8.0.0", + "System.Runtime.CompilerServices.Unsafe": "6.0.0", + "System.Text.Json": "8.0.0", + "System.Threading.Channels": "8.0.0" + } + }, + "StackExchange.Redis": { + "type": "CentralTransitive", + "requested": "[2.7.27, )", + "resolved": "2.7.27", + "contentHash": "Uqc2OQHglqj9/FfGQ6RkKFkZfHySfZlfmbCl+hc+u2I/IqunfelQ7QJi7ZhvAJxUtu80pildVX6NPLdDaUffOw==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "5.0.0", + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8", + "System.IO.Compression": "4.3.0", + "System.Threading.Channels": "5.0.0" + } + }, + "ZooKeeperNetEx": { + "type": "CentralTransitive", + "requested": "[3.4.12.4, )", + "resolved": "3.4.12.4", + "contentHash": "YECtByVSH7TRjQKplwOWiKyanCqYE5eEkGk5YtHJgsnbZ6+p1o0Gvs5RIsZLotiAVa6Niez1BJyKY/RDY/L6zg==" + } + }, + ".NETFramework,Version=v4.7.2/win7-x86": { + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "jXw9MlUu/kRfEU0WyTptAVueupqIeE3/rl0EZDMlf8pcvJnitQ8HeVEp69rZdaStXwTV72boi/Bhw8lOeO+U2w==", + "dependencies": { + "System.Security.Permissions": "6.0.0" + } + }, + "System.IO.Compression": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "YHndyoiV90iu4iKG115ibkhrG+S3jBm8Ap9OwoUAzO5oPDAWcr0SFwQFm0HjM8WkEZWo0zvLTyLmbvTkW1bXgg==" + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Runtime.InteropServices.RuntimeInformation": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "cbz4YJMqRDR7oLeMRbdYv7mYzc++17lNhScCX0goO2XpGWdvAt60CGN+FHdePUEHCe/Jy9jUlvNAiNdM+7jsOw==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==", + "dependencies": { + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "4.7.0", + "contentHash": "ehYW0m9ptxpGWvE4zgqongBVWpSDU/JCFD4K7krxkQwSz/sFQjEXCUqpvencjy6DYDbn7Ig09R8GFffu8TtneQ==" + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "Microsoft.Data.SqlClient": { + "type": "CentralTransitive", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "System.Buffers": "4.5.1", + "System.Configuration.ConfigurationManager": "6.0.1", + "System.Runtime.InteropServices.RuntimeInformation": "4.3.0", + "System.Text.Encodings.Web": "6.0.0" + } + } + }, + "net8.0": { + "Microsoft.NET.ILLink.Tasks": { + "type": "Direct", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "hKTrehpfVzOhAz0mreaTAZgbz0DrMEbWq4n3hAo8Ks6WdxdqQhNPvzOqn9VygKuWf1bmxPdraqzTaXriO/sn0A==" + }, + "Azure.Core": { + "type": "Transitive", + "resolved": "1.36.0", + "contentHash": "vwqFZdHS4dzPlI7FFRkPx9ctA+aGGeRev3gnzG8lntWvKMmBhAmulABi1O9CEvS3/jzYt7yA+0pqVdxkpAd7dQ==", + "dependencies": { + "Microsoft.Bcl.AsyncInterfaces": "1.1.1", + "System.Diagnostics.DiagnosticSource": "6.0.1", + "System.Memory.Data": "1.0.2", + "System.Numerics.Vectors": "4.5.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Identity": { + "type": "Transitive", + "resolved": "1.10.3", + "contentHash": "l1Xm2MWOF2Mzcwuarlw8kWQXLZk3UeB55aQXVyjj23aBfDwOZ3gu5GP2kJ6KlmZeZv2TCzw7x4L3V36iNr3gww==", + "dependencies": { + "Azure.Core": "1.35.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.Identity.Client.Extensions.Msal": "4.56.0", + "System.Memory": "4.5.4", + "System.Security.Cryptography.ProtectedData": "4.7.0", + "System.Text.Json": "4.7.2", + "System.Threading.Tasks.Extensions": "4.5.4" + } + }, + "Azure.Storage.Common": { + "type": "Transitive", + "resolved": "12.18.1", + "contentHash": "ohCslqP9yDKIn+DVjBEOBuieB1QwsUCz+BwHYNaJ3lcIsTSiI4Evnq81HcKe8CqM8qvdModbipVQKpnxpbdWqA==", + "dependencies": { + "Azure.Core": "1.36.0", + "System.IO.Hashing": "6.0.0" + } + }, + "Microsoft.Bcl.AsyncInterfaces": { + "type": "Transitive", + "resolved": "1.1.1", + "contentHash": "yuvf07qFWFqtK3P/MRkEKLhn5r2UbSpVueRziSqj0yJQIKFwG1pq9mOayK3zE5qZCTs0CbrwL9M6R8VwqyGy2w==" + }, + "Microsoft.CSharp": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "kaj6Wb4qoMuH3HySFJhxwQfe8R/sJsNJnANrvv8WdFPMoNbKY5htfNscv+LHCu5ipz+49m2e+WQXpLXr9XYemQ==" + }, + "Microsoft.Data.SqlClient.SNI.runtime": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "po1jhvFd+8pbfvJR/puh+fkHi0GRanAdvayh/0e47yaM6CXWZ6opUjCMFuYlAnD2LcbyvQE7fPJKvogmaUcN+w==" + }, + "Microsoft.Extensions.DependencyInjection.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "cjWrLkJXK0rs4zofsK4bSdg+jhDLTaxrkXu4gS6Y7MAlCvRyNNgwY/lJi5RDlQOnSZweHqoyvgvbdvQsRIW+hg==" + }, + "Microsoft.Extensions.Logging.Abstractions": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "arDBqTgFCyS0EvRV7O3MZturChstm50OJ0y9bDJvAcmEPJm0FFpFyjU/JLYyStNGGey081DvnQYlncNX5SJJGA==", + "dependencies": { + "Microsoft.Extensions.DependencyInjection.Abstractions": "8.0.0" + } + }, + "Microsoft.Identity.Client": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "rr4zbidvHy9r4NvOAs5hdd964Ao2A0pAeFBJKR95u1CJAVzbd1p6tPTXUZ+5ld0cfThiVSGvz6UHwY6JjraTpA==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.22.0" + } + }, + "Microsoft.Identity.Client.Extensions.Msal": { + "type": "Transitive", + "resolved": "4.56.0", + "contentHash": "H12YAzEGK55vZ+QpxUzozhW8ZZtgPDuWvgA0JbdIR9UhMUplj29JhIgE2imuH8W2Nw9D8JKygR1uxRFtpSNcrg==", + "dependencies": { + "Microsoft.Identity.Client": "4.56.0", + "System.IO.FileSystem.AccessControl": "5.0.0", + "System.Security.Cryptography.ProtectedData": "4.5.0" + } + }, + "Microsoft.IdentityModel.Abstractions": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "xuR8E4Rd96M41CnUSCiOJ2DBh+z+zQSmyrYHdYhD6K4fXBcQGVnRCFQ0efROUYpP+p0zC1BLKr0JRpVuujTZSg==" + }, + "Microsoft.IdentityModel.JsonWebTokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "9wxai3hKgZUb4/NjdRKfQd0QJvtXKDlvmGMYACbEC8DFaicMFCFhQFZq9ZET1kJLwZahf2lfY5Gtcpsx8zYzbg==", + "dependencies": { + "Microsoft.IdentityModel.Tokens": "6.35.0", + "System.Text.Encoding": "4.3.0", + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.IdentityModel.Logging": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "jePrSfGAmqT81JDCNSY+fxVWoGuJKt9e6eJ+vT7+quVS55nWl//jGjUQn4eFtVKt4rt5dXaleZdHRB9J9AJZ7Q==", + "dependencies": { + "Microsoft.IdentityModel.Abstractions": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "BPQhlDzdFvv1PzaUxNSk+VEPwezlDEVADIKmyxubw7IiELK18uJ06RQ9QKKkds30XI+gDu9n8j24XQ8w7fjWcg==", + "dependencies": { + "Microsoft.IdentityModel.Logging": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "Microsoft.IdentityModel.Protocols.OpenIdConnect": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "LMtVqnECCCdSmyFoCOxIE5tXQqkOLrvGrL7OxHg41DIm1bpWtaCdGyVcTAfOQpJXvzND9zUKIN/lhngPkYR8vg==", + "dependencies": { + "Microsoft.IdentityModel.Protocols": "6.35.0", + "System.IdentityModel.Tokens.Jwt": "6.35.0" + } + }, + "Microsoft.IdentityModel.Tokens": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "RN7lvp7s3Boucg1NaNAbqDbxtlLj5Qeb+4uSS1TeK5FSBVM40P4DKaTKChT43sHyKfh7V0zkrMph6DdHvyA4bg==", + "dependencies": { + "Microsoft.CSharp": "4.5.0", + "Microsoft.IdentityModel.Logging": "6.35.0", + "System.Security.Cryptography.Cng": "4.5.0" + } + }, + "Microsoft.NETCore.Platforms": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==" + }, + "Microsoft.NETCore.Targets": { + "type": "Transitive", + "resolved": "1.1.0", + "contentHash": "aOZA3BWfz9RXjpzt0sRJJMjAscAUm3Hoa4UWAfceV9UTYxgwZ1lZt5nO2myFf+/jetYQo4uTP7zS8sJY67BBxg==" + }, + "Microsoft.SqlServer.Server": { + "type": "Transitive", + "resolved": "1.0.0", + "contentHash": "N4KeF3cpcm1PUHym1RmakkzfkEv3GRMyofVv40uXsQhCQeglr2OHNcUk2WOG51AKpGO8ynGpo9M/kFXSzghwug==" + }, + "Microsoft.Win32.SystemEvents": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "hqTM5628jSsQiv+HGpiq3WKBl2c8v1KZfby2J6Pr7pEPlK9waPdgEO6b8A/+/xn/yZ9ulv8HuqK71ONy2tg67A==" + }, + "Oracle.ManagedDataAccess.Core": { + "type": "Transitive", + "resolved": "3.21.130", + "contentHash": "bXNwPyAaDivO84HEYiegK7r/LleSEfA0nc70bE88wkqd1E0Q1+r/SUbJ51xOK2vk6iHbTSMuhnC79BU8svPBjQ==", + "dependencies": { + "System.Diagnostics.PerformanceCounter": "6.0.1", + "System.DirectoryServices": "6.0.1", + "System.DirectoryServices.Protocols": "6.0.2" + } + }, + "Pipelines.Sockets.Unofficial": { + "type": "Transitive", + "resolved": "2.2.8", + "contentHash": "zG2FApP5zxSx6OcdJQLbZDk2AVlN2BNQD6MorwIfV6gVj0RRxWPEp2LXAxqDGZqeNV1Zp0BNPcNaey/GXmTdvQ==", + "dependencies": { + "System.IO.Pipelines": "5.0.1" + } + }, + "System.Configuration.ConfigurationManager": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "JlYi9XVvIREURRUlGMr1F6vOFLk7YSY4p1vHo4kX3tQ0AGrjqlRWHDi66ImHhy6qwXBG3BJ6Y1QlYQ+Qz6Xgww==", + "dependencies": { + "System.Diagnostics.EventLog": "8.0.0", + "System.Security.Cryptography.ProtectedData": "8.0.0" + } + }, + "System.Diagnostics.DiagnosticSource": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "KiLYDu2k2J82Q9BJpWiuQqCkFjRBWVq4jDzKKWawVi9KWzyD0XG3cmfX0vqTQlL14Wi9EufJrbL0+KCLTbqWiQ==", + "dependencies": { + "System.Runtime.CompilerServices.Unsafe": "6.0.0" + } + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "fdYxcRjQqTTacKId/2IECojlDSFvp7LP5N78+0z/xH7v/Tuw5ZAxu23Y6PTCRinqyu2ePx+Gn1098NC6jM6d+A==" + }, + "System.Diagnostics.PerformanceCounter": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "dDl7Gx3bmSrM2k2ZIm+ucEJnLloZRyvfQF1DvfvATcGF3jtaUBiPvChma+6ZcZzxWMirN3kCywkW7PILphXyMQ==", + "dependencies": { + "System.Configuration.ConfigurationManager": "6.0.0" + } + }, + "System.DirectoryServices": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "935IbO7h5FDGYxeO3cbx/CuvBBuk/VI8sENlfmXlh1pupNOB3LAGzdYdPY8CawGJFP7KNrHK5eUlsFoz3F6cuA==", + "dependencies": { + "System.Security.AccessControl": "6.0.0", + "System.Security.Permissions": "6.0.0" + } + }, + "System.DirectoryServices.Protocols": { + "type": "Transitive", + "resolved": "6.0.2", + "contentHash": "vDDPWwHn3/DNZ+kPkdXHoada+tKPEC9bVqDOr4hK6HBSP7hGCUTA0Zw6WU5qpGaqa5M1/V+axHMIv+DNEbIf6g==" + }, + "System.Drawing.Common": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "NfuoKUiP2nUWwKZN6twGqXioIe1zVD0RIj2t976A+czLHr2nY454RwwXs6JU9Htc6mwqL6Dn/nEL3dpVf2jOhg==", + "dependencies": { + "Microsoft.Win32.SystemEvents": "6.0.0" + } + }, + "System.IdentityModel.Tokens.Jwt": { + "type": "Transitive", + "resolved": "6.35.0", + "contentHash": "yxGIQd3BFK7F6S62/7RdZk3C/mfwyVxvh6ngd1VYMBmbJ1YZZA9+Ku6suylVtso0FjI0wbElpJ0d27CdsyLpBQ==", + "dependencies": { + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Tokens": "6.35.0" + } + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.IO.Hashing": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "Rfm2jYCaUeGysFEZjDe7j1R4x6Z6BzumS/vUT5a1AA/AWJuGX71PoGB0RmpyX3VmrGqVnAwtfMn39OHR8Y/5+g==" + }, + "System.IO.Pipelines": { + "type": "Transitive", + "resolved": "5.0.1", + "contentHash": "qEePWsaq9LoEEIqhbGe6D5J8c9IqQOUuTzzV6wn1POlfdLkJliZY3OlB0j0f17uMWlqZYjH7txj+2YbyrIA8Yg==" + }, + "System.Memory": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "1MbJTHS1lZ4bS4FmsJjnuGJOu88ZzTT2rLvrhW7Ygic+pC0NWA+3hgAen0HRdsocuQXCkUTdFn9yHJJhsijDXw==" + }, + "System.Memory.Data": { + "type": "Transitive", + "resolved": "1.0.2", + "contentHash": "JGkzeqgBsiZwKJZ1IxPNsDFZDhUvuEdX8L8BDC8N3KOj+6zMcNU28CNN59TpZE/VJYy9cP+5M+sbxtWJx3/xtw==", + "dependencies": { + "System.Text.Encodings.Web": "4.7.2", + "System.Text.Json": "4.6.0" + } + }, + "System.Numerics.Vectors": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "QQTlPTl06J/iiDbJCiepZ4H//BVraReU4O4EoRw1U02H5TLUIT7xn3GnDp9AXPSlJUDyFs4uWjWafNX6WrAojQ==" + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0" + } + }, + "System.Runtime.Caching": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "4TmlmvGp4kzZomm7J2HJn6IIx0UUrQyhBDyb5O1XiunZlQImXW+B8b7W/sTPcXhSf9rp5NR5aDtQllwbB5elOQ==", + "dependencies": { + "System.Configuration.ConfigurationManager": "8.0.0" + } + }, + "System.Runtime.CompilerServices.Unsafe": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "/iUeP3tq1S0XdNNoMz5C9twLSrM/TH+qElHkXWaPvuNOt+99G75NrV0OS2EqHx5wMN7popYjpc8oTjC1y16DLg==" + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==" + }, + "System.Security.Cryptography.Cng": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "WG3r7EyjUe9CMPFSs6bty5doUqT+q9pbI80hlNzo2SkPkZ4VTuZkGWjpp77JB8+uaL4DFPRdBsAY+DX3dBK92A==" + }, + "System.Security.Cryptography.ProtectedData": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "+TUFINV2q2ifyXauQXRwy4CiBhqvDEDZeVJU7qfxya4aRYOKzVBpN+4acx25VcPB9ywUN6C0n8drWl110PhZEg==" + }, + "System.Security.Permissions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "T/uuc7AklkDoxmcJ7LGkyX1CcSviZuLCa4jg3PekfJ7SU0niF0IVTXwUiNVP9DSpzou2PpxJ+eNY2IfDM90ZCg==", + "dependencies": { + "System.Security.AccessControl": "6.0.0", + "System.Windows.Extensions": "6.0.0" + } + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0" + } + }, + "System.Text.Encodings.Web": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "iTUgB/WtrZ1sWZs84F2hwyQhiRH6QNjQv2DkwrH+WP6RoFga2Q1m3f9/Q7FG8cck8AdHitQkmkXSY8qylcDmuA==" + }, + "System.Text.Json": { + "type": "Transitive", + "resolved": "4.7.2", + "contentHash": "TcMd95wcrubm9nHvJEQs70rC0H/8omiSGGpU4FQ/ZA1URIqD4pjmFJh2Mfv1yH1eHgJDWTi2hMDXwTET+zOOyg==" + }, + "System.Threading.Tasks.Extensions": { + "type": "Transitive", + "resolved": "4.5.4", + "contentHash": "zteT+G8xuGu6mS+mzDzYXbzS7rd3K6Fjb9RiZlYlJPam2/hU7JCBZBVEcywNuR+oZ1ncTvc/cq0faRr3P01OVg==" + }, + "System.Windows.Extensions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "IXoJOXIqc39AIe+CIR7koBtRGMiCt/LPM3lI+PELtDIy9XdyeSrwXFdWV9dzJ2Awl0paLWUaknLxFQ5HpHZUog==", + "dependencies": { + "System.Drawing.Common": "6.0.0" + } + }, + "distributedlock": { + "type": "Project", + "dependencies": { + "DistributedLock.Azure": "[1.0.1, )", + "DistributedLock.FileSystem": "[1.0.2, )", + "DistributedLock.MySql": "[1.0.2, )", + "DistributedLock.Oracle": "[1.0.3, )", + "DistributedLock.Postgres": "[1.1.0, )", + "DistributedLock.Redis": "[1.0.3, )", + "DistributedLock.SqlServer": "[1.0.4, )", + "DistributedLock.WaitHandles": "[1.0.1, )", + "DistributedLock.ZooKeeper": "[1.0.0, )" + } + }, + "distributedlock.azure": { + "type": "Project", + "dependencies": { + "Azure.Storage.Blobs": "[12.19.1, )", + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.core": { + "type": "Project" + }, + "distributedlock.filesystem": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )" + } + }, + "distributedlock.mysql": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "MySqlConnector": "[2.3.5, )" + } + }, + "distributedlock.oracle": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Oracle.ManagedDataAccess.Core": "[3.21.130, )" + } + }, + "distributedlock.postgres": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Npgsql": "[8.0.2, )" + } + }, + "distributedlock.redis": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "StackExchange.Redis": "[2.7.27, )" + } + }, + "distributedlock.sqlserver": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "Microsoft.Data.SqlClient": "[5.2.0, )" + } + }, + "distributedlock.waithandles": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "System.Threading.AccessControl": "[8.0.0, )" + } + }, + "distributedlock.zookeeper": { + "type": "Project", + "dependencies": { + "DistributedLock.Core": "[1.0.6, )", + "ZooKeeperNetEx": "[3.4.12.4, )" + } + }, + "Azure.Storage.Blobs": { + "type": "CentralTransitive", + "requested": "[12.19.1, )", + "resolved": "12.19.1", + "contentHash": "x43hWFJ4sPQ23TD4piCwT+KlQpZT8pNDAzqj6yUCqh+WJ2qcQa17e1gh6ZOeT2QNFQTTDSuR56fm2bIV7i11/w==", + "dependencies": { + "Azure.Storage.Common": "12.18.1", + "System.Text.Json": "4.7.2" + } + }, + "Microsoft.Data.SqlClient": { + "type": "CentralTransitive", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI.runtime": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "Microsoft.SqlServer.Server": "1.0.0", + "System.Configuration.ConfigurationManager": "8.0.0", + "System.Runtime.Caching": "8.0.0" + } + }, + "MySqlConnector": { + "type": "CentralTransitive", + "requested": "[2.3.5, )", + "resolved": "2.3.5", + "contentHash": "AmEfUPkFl+Ev6jJ8Dhns3CYHBfD12RHzGYWuLt6DfG6/af6YvOMyPz74ZPPjBYQGRJkumD2Z48Kqm8s5DJuhLA==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "7.0.1" + } + }, + "Npgsql": { + "type": "CentralTransitive", + "requested": "[8.0.2, )", + "resolved": "8.0.2", + "contentHash": "MuJzLoWCaQhQAR3oh66YR0Ir6mxuezncGX3f8wxvAc21g0+9HICktJQlqMoODhxztZKXE5k9GxRxqUAN+vPb4g==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "8.0.0" + } + }, + "StackExchange.Redis": { + "type": "CentralTransitive", + "requested": "[2.7.27, )", + "resolved": "2.7.27", + "contentHash": "Uqc2OQHglqj9/FfGQ6RkKFkZfHySfZlfmbCl+hc+u2I/IqunfelQ7QJi7ZhvAJxUtu80pildVX6NPLdDaUffOw==", + "dependencies": { + "Microsoft.Extensions.Logging.Abstractions": "6.0.0", + "Pipelines.Sockets.Unofficial": "2.2.8" + } + }, + "System.Threading.AccessControl": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==" + }, + "ZooKeeperNetEx": { + "type": "CentralTransitive", + "requested": "[3.4.12.4, )", + "resolved": "3.4.12.4", + "contentHash": "YECtByVSH7TRjQKplwOWiKyanCqYE5eEkGk5YtHJgsnbZ6+p1o0Gvs5RIsZLotiAVa6Niez1BJyKY/RDY/L6zg==" + } + }, + "net8.0/win7-x86": { + "Microsoft.Data.SqlClient.SNI.runtime": { + "type": "Transitive", + "resolved": "5.2.0", + "contentHash": "po1jhvFd+8pbfvJR/puh+fkHi0GRanAdvayh/0e47yaM6CXWZ6opUjCMFuYlAnD2LcbyvQE7fPJKvogmaUcN+w==" + }, + "Microsoft.Win32.SystemEvents": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "hqTM5628jSsQiv+HGpiq3WKBl2c8v1KZfby2J6Pr7pEPlK9waPdgEO6b8A/+/xn/yZ9ulv8HuqK71ONy2tg67A==" + }, + "runtime.any.System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "fRS7zJgaG9NkifaAxGGclDDoRn9HC7hXACl52Or06a/fxdzDajWb5wov3c6a+gVSlekRoexfjwQSK9sh5um5LQ==", + "dependencies": { + "System.Private.Uri": "4.3.0" + } + }, + "runtime.any.System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "+ihI5VaXFCMVPJNstG4O4eo1CfbrByLxRrQQTqOTp1ttK0kUKDqOdBSTaCB2IBk/QtjDrs6+x4xuezyMXdm0HQ==" + }, + "runtime.win7.System.Private.Uri": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "Q+IBgaPYicSQs2tBlmXqbS25c/JLIthWrgrpMwxKSOobW/OqIMVFruUGfuaz4QABVzV8iKdCAbN7APY7Tclbnw==" + }, + "System.Diagnostics.EventLog": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "fdYxcRjQqTTacKId/2IECojlDSFvp7LP5N78+0z/xH7v/Tuw5ZAxu23Y6PTCRinqyu2ePx+Gn1098NC6jM6d+A==" + }, + "System.Diagnostics.PerformanceCounter": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "dDl7Gx3bmSrM2k2ZIm+ucEJnLloZRyvfQF1DvfvATcGF3jtaUBiPvChma+6ZcZzxWMirN3kCywkW7PILphXyMQ==", + "dependencies": { + "System.Configuration.ConfigurationManager": "6.0.0" + } + }, + "System.DirectoryServices": { + "type": "Transitive", + "resolved": "6.0.1", + "contentHash": "935IbO7h5FDGYxeO3cbx/CuvBBuk/VI8sENlfmXlh1pupNOB3LAGzdYdPY8CawGJFP7KNrHK5eUlsFoz3F6cuA==", + "dependencies": { + "System.Security.AccessControl": "6.0.0", + "System.Security.Permissions": "6.0.0" + } + }, + "System.DirectoryServices.Protocols": { + "type": "Transitive", + "resolved": "6.0.2", + "contentHash": "vDDPWwHn3/DNZ+kPkdXHoada+tKPEC9bVqDOr4hK6HBSP7hGCUTA0Zw6WU5qpGaqa5M1/V+axHMIv+DNEbIf6g==" + }, + "System.Drawing.Common": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "NfuoKUiP2nUWwKZN6twGqXioIe1zVD0RIj2t976A+czLHr2nY454RwwXs6JU9Htc6mwqL6Dn/nEL3dpVf2jOhg==", + "dependencies": { + "Microsoft.Win32.SystemEvents": "6.0.0" + } + }, + "System.IO.FileSystem.AccessControl": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "SxHB3nuNrpptVk+vZ/F+7OHEpoHUIKKMl02bUmYHQr1r+glbZQxs7pRtsf4ENO29TVm2TH3AEeep2fJcy92oYw==", + "dependencies": { + "System.Security.AccessControl": "5.0.0", + "System.Security.Principal.Windows": "5.0.0" + } + }, + "System.Private.Uri": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "I4SwANiUGho1esj4V4oSlPllXjzCZDE+5XXso2P03LW2vOda2Enzh8DWOxwN6hnrJyp314c7KuVu31QYhRzOGg==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "runtime.win7.System.Private.Uri": "4.3.0" + } + }, + "System.Runtime": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "JufQi0vPQ0xGnAczR13AUFglDyVYt4Kqnz1AZaiKZ5+GICq0/1MH/mO/eAJHt/mHW1zjKBJd7kV26SrxddAhiw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "runtime.any.System.Runtime": "4.3.0" + } + }, + "System.Runtime.Caching": { + "type": "Transitive", + "resolved": "8.0.0", + "contentHash": "4TmlmvGp4kzZomm7J2HJn6IIx0UUrQyhBDyb5O1XiunZlQImXW+B8b7W/sTPcXhSf9rp5NR5aDtQllwbB5elOQ==", + "dependencies": { + "System.Configuration.ConfigurationManager": "8.0.0" + } + }, + "System.Security.AccessControl": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "AUADIc0LIEQe7MzC+I0cl0rAT8RrTAKFHl53yHjEUzNVIaUlhFY11vc2ebiVJzVBuOzun6F7FBA+8KAbGTTedQ==" + }, + "System.Security.Cryptography.Cng": { + "type": "Transitive", + "resolved": "4.5.0", + "contentHash": "WG3r7EyjUe9CMPFSs6bty5doUqT+q9pbI80hlNzo2SkPkZ4VTuZkGWjpp77JB8+uaL4DFPRdBsAY+DX3dBK92A==" + }, + "System.Security.Principal.Windows": { + "type": "Transitive", + "resolved": "5.0.0", + "contentHash": "t0MGLukB5WAVU9bO3MGzvlGnyJPgUlcwerXn1kzBRjwLKixT96XV0Uza41W49gVd8zEMFu9vQEFlv0IOrytICA==" + }, + "System.Text.Encoding": { + "type": "Transitive", + "resolved": "4.3.0", + "contentHash": "BiIg+KWaSDOITze6jGQynxg64naAPtqGHBwDrLaCtixsa5bKiR8dpPOHA7ge3C0JJQizJE+sfkz1wV+BAKAYZw==", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0", + "Microsoft.NETCore.Targets": "1.1.0", + "System.Runtime": "4.3.0", + "runtime.any.System.Text.Encoding": "4.3.0" + } + }, + "System.Windows.Extensions": { + "type": "Transitive", + "resolved": "6.0.0", + "contentHash": "IXoJOXIqc39AIe+CIR7koBtRGMiCt/LPM3lI+PELtDIy9XdyeSrwXFdWV9dzJ2Awl0paLWUaknLxFQ5HpHZUog==", + "dependencies": { + "System.Drawing.Common": "6.0.0" + } + }, + "Microsoft.Data.SqlClient": { + "type": "CentralTransitive", + "requested": "[5.2.0, )", + "resolved": "5.2.0", + "contentHash": "3alfyqRN3ELRtdvU1dGtLBRNQqprr3TJ0WrUJfMISPwg1nPUN2P3Lelah68IKWuV27Ceb7ig95hWNHFTSXfxMg==", + "dependencies": { + "Azure.Identity": "1.10.3", + "Microsoft.Data.SqlClient.SNI.runtime": "5.2.0", + "Microsoft.Identity.Client": "4.56.0", + "Microsoft.IdentityModel.JsonWebTokens": "6.35.0", + "Microsoft.IdentityModel.Protocols.OpenIdConnect": "6.35.0", + "Microsoft.SqlServer.Server": "1.0.0", + "System.Configuration.ConfigurationManager": "8.0.0", + "System.Runtime.Caching": "8.0.0" + } + }, + "System.Threading.AccessControl": { + "type": "CentralTransitive", + "requested": "[8.0.0, )", + "resolved": "8.0.0", + "contentHash": "cIed5+HuYz+eV9yu9TH95zPkqmm1J9Qps9wxjB335sU8tsqc2kGdlTEH9FZzZeCS8a7mNSEsN8ZkyhQp1gfdEw==" + } + } + } +} \ No newline at end of file diff --git a/src/package.readme.md b/src/package.readme.md new file mode 100644 index 0000000..0b319fc --- /dev/null +++ b/src/package.readme.md @@ -0,0 +1,11 @@ +DistributedLock is a .NET library that provides robust and easy-to-use distributed mutexes, reader-writer locks, and semaphores based on a variety of underlying technologies. + +With DistributedLock, synchronizing access to a region of code across multiple applications/machines is as simple as: +```C# +await using (await myDistributedLock.AcquireAsync()) +{ + // I hold the lock here +} +``` + +**Read the documentation [here](https://github.com/madelson/DistributedLock).** \ No newline at end of file