Skip to content

Commit eec4e0b

Browse files
authored
Merge pull request #200 from madelson/release-2.4
Release 2.4
2 parents 8f892e5 + 3c0a3fb commit eec4e0b

130 files changed

Lines changed: 9516 additions & 478 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,17 @@ await using (await myDistributedLock.AcquireAsync())
1414

1515
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*.
1616

17-
- **[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
18-
- **[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
19-
- **[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
20-
- **[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
21-
- **[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
22-
- **[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
23-
- **[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
24-
- **[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
25-
- **[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)
17+
- **[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)
18+
: uses Microsoft SQL Server
19+
- **[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)
20+
: uses Postgresql
21+
- **[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
22+
- **[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
23+
- **[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
24+
- **[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
25+
- **[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
26+
- **[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
27+
- **[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)
2628

2729
**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.
2830

@@ -136,12 +138,23 @@ public class SomeService
136138

137139
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.
138140

141+
Setup steps for working with the repository locally are documented [here](docs/Developing%20DistributedLock.md).
142+
139143
## Release notes
144+
- 2.4
145+
- 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)
146+
- 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!
147+
- Reduce occurrence of `UnobservedTaskException`s thrown by the library ([#192](https://github.com/madelson/DistributedLock/issues/192), DistributedLock.Core 1.0.6)
148+
- 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!
149+
- Improve directory creation concurrency handling for `FileDistributedLock` on Linux/.NET 8 ([#195](), DistributedLock.FileSystem 1.0.2)
150+
- 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)
151+
- New API documentation on [dndocs](https://dndocs.com/). Thanks @NeuroXiq!
152+
- New documentation for contributors to get the project running locally (see [Contributing](#contributing))
140153
- 2.3.4
141154
- 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!
142155
- 2.3.3
143156
- Update Microsoft.Data.SqlClient due to vulnerabilities ([#149](https://github.com/madelson/DistributedLock/issues/149), DistributedLock.SqlServer 1.0.3)
144-
- Update versions of Oracle.ManagedDataAccess and Oracle.ManagedDataAccess.Core due to vulnerabilities (DistributedLock.Oracle 1.0.2)
157+
- Update versions of Oracle.ManagedDataAccess and Oracle.ManagedDataAccess.Core due to vulnerabilities (DistributedLock.Oracle 1.0.2)
145158
- 2.3.2
146159
- 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!
147160
- 2.3.1

appveyor.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
version: 1.0.{build}
22

3-
image:
3+
image:
4+
# Ubuntu2204 needed for .NET 8 for now (see https://www.appveyor.com/docs/linux-images-software/)
5+
- Ubuntu2204
46
- Visual Studio 2022
5-
- Ubuntu
67

78
build_script:
89
- dotnet build src/DistributedLock.sln -c Release
910

1011
test_script:
11-
- dotnet test src/DistributedLock.sln -c Release -f netcoreapp3.1 --no-build --filter TestCategory=CI
12+
- dotnet test src/DistributedLock.sln -c Release -f net8.0 --no-build --filter TestCategory=CI
1213

1314
for:
1415
-

docs/Developing DistributedLock.md

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Developing DistributedLock
2+
3+
## Installing back-ends for testing
4+
5+
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.
6+
7+
### Azure
8+
9+
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.
10+
11+
### MySQL
12+
13+
The MySQL driver covers both MySQL and MariaDB; so we'll need to install both.
14+
15+
#### MariaDB
16+
17+
The MariaDB installer can be downloaded [here](https://mariadb.org/download/?t=mariadb&p=mariadb&os=windows&cpu=x86_64&pkg=msi&m=acorn).
18+
19+
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):
20+
21+
```ini
22+
# activates the performance_schema tables which are needed by DistributedLock tests
23+
performance_schema=ON
24+
```
25+
26+
After doing this, restart MariaDB (on Windows, do this in the Services app).
27+
28+
Next, create the `distributed_lock` database and a user for the tests to run as:
29+
```sql
30+
CREATE DATABASE distributed_lock;
31+
CREATE USER 'DistributedLock'@'localhost' IDENTIFIED BY '<password>';
32+
GRANT ALL PRIVILEGES ON distributed_lock.* TO 'DistributedLock'@'localhost';
33+
GRANT SELECT ON performance_schema.* TO 'DistributedLock'@'localhost';
34+
```
35+
36+
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.
37+
38+
#### MySQL
39+
40+
You can install MySQL from [here](https://dev.mysql.com/downloads/mysql/). Run on port 3307 to avoid conflicting with MariaDB.
41+
42+
Add your username and password to `DistributedLock.Tests/credentials/mysql.txt`, with the username on line 1 and the password on line 2.
43+
44+
### Oracle
45+
46+
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.
47+
48+
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.
49+
50+
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.
51+
52+
### Postgres
53+
54+
You can install Postgres from [here](https://www.enterprisedb.com/downloads/postgres-postgresql-downloads).
55+
56+
In `C:\Program Files\PostgreSQL\<version>\data\postgresql.conf`, update `max_connections` to 200.
57+
58+
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.
59+
60+
### SQL Server
61+
62+
Download SQL developer edition from [here](https://www.microsoft.com/en-us/sql-server/sql-server-downloads).
63+
64+
The tests connect via integrated security.
65+
66+
### Redis
67+
68+
Install Redis locally. On Windows, install it via WSL as described [here](https://developer.redis.com/create/windows/).
69+
70+
You do not need it running as a service: the tests will start and stop instances automatically.
71+
72+
### ZooKeeper
73+
74+
Download a ZooKeeper installation by going to [https://zookeeper.apache.org/](https://zookeeper.apache.org/)->Documentation->Release ...->Getting Started->Download->stable.
75+
76+
Extract the zip archive, and within it copy `zoo_sample.cfg` to `zoo.cfg`.
77+
78+
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.
79+
80+
Also, install Java Development Kit (JDK) because ZooKeeper runs on Java.

docs/DistributedLock.Postgres.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ In addition to specifying the `key`, Postgres-based locks allow you to specify e
3535
In addition to specifying the `key`, several tuning options are available for `connectionString`-based locks:
3636

3737
- `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`).
38+
- `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.
3839
- `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!).
3940

4041

docs/DistributedLock.SqlServer.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,5 @@ SQL-based locks can be constructed with a connection string, an `IDbConnection`,
2828
When connecting using a `connectionString`, several other tuning options can also be specified.
2929

3030
- `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.
31-
- `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.
32-
- `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!).
31+
- `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.
32+
- `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.

src/Directory.Build.props

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<Project>
2+
<PropertyGroup>
3+
<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>
4+
<!-- Recommended in https://devblogs.microsoft.com/dotnet/creating-aot-compatible-libraries/ -->
5+
<IsAotCompatible Condition="$([MSBuild]::IsTargetFrameworkCompatible('$(TargetFramework)', 'net7.0'))">true</IsAotCompatible>
6+
<PackageReadmeFile>package.readme.md</PackageReadmeFile>
7+
</PropertyGroup>
8+
9+
<ItemGroup>
10+
<!-- See https://learn.microsoft.com/en-us/nuget/reference/errors-and-warnings/nu5039#solution -->
11+
<None Include="$(MSBuildThisFileDirectory)package.readme.md" Pack="true" PackagePath="" />
12+
</ItemGroup>
13+
</Project>

src/Directory.Packages.props

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<Project>
2+
<PropertyGroup>
3+
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
4+
<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>
5+
</PropertyGroup>
6+
<ItemGroup>
7+
<PackageVersion Include="Microsoft.SourceLink.GitHub" Version="8.0.0" />
8+
<PackageVersion Include="Microsoft.CodeAnalysis.PublicApiAnalyzers" Version="3.3.4" />
9+
<PackageVersion Include="Azure.Storage.Blobs" Version="12.19.1" />
10+
<PackageVersion Include="Nullable" Version="1.3.1" Condition="'$(TargetFramework)' != 'netstandard2.1'" />
11+
<PackageVersion Include="MySqlConnector" Version="2.3.5" />
12+
<PackageVersion Include="Oracle.ManagedDataAccess.Core" Version="3.21.130" Condition="'$(TargetFramework)' == 'netstandard2.1'" />
13+
<PackageVersion Include="Oracle.ManagedDataAccess" Version="21.13.0" Condition="'$(TargetFramework)' == 'net462'"/>
14+
<PackageVersion Include="Npgsql" Version="8.0.2" />
15+
<PackageVersion Include="StackExchange.Redis" Version="2.7.27" />
16+
<PackageVersion Include="Microsoft.Data.SqlClient" Version="5.2.0" />
17+
<PackageVersion Include="nunit" Version="3.14.0" />
18+
<PackageVersion Include="nunit3testadapter" Version="4.5.0" />
19+
<PackageVersion Include="Microsoft.NET.Test.SDK" Version="17.9.0" />
20+
<PackageVersion Include="MedallionShell.StrongName" Version="1.6.2" />
21+
<PackageVersion Include="System.Data.SqlClient" Version="4.8.6" />
22+
<PackageVersion Include="Moq" Version="4.20.70" />
23+
<PackageVersion Include="System.Threading.AccessControl" Version="8.0.0" Condition="'$(TargetFramework)' != 'net462'" />
24+
<PackageVersion Include="ZooKeeperNetEx" Version="3.4.12.4" />
25+
<PackageVersion Include="IsExternalInit" Version="1.0.3" />
26+
<PackageVersion Include="Microsoft.Bcl.AsyncInterfaces" Version="8.0.0" Condition="'$(TargetFramework)' == 'netstandard2.0' OR '$(TargetFramework)' == 'net462'" />
27+
<PackageVersion Include="System.ValueTuple" Version="4.5.0" Condition="'$(TargetFramework)' == 'net462'" />
28+
</ItemGroup>
29+
</Project>

0 commit comments

Comments
 (0)