Unable to create MySqlDistributedSynchronizationProvider by using MySqlConnection via"ProvidePasswordCallback"
I couldn't create MySqlDistributedSynchronizationProvider by passing MySQLConnection.
But It's working with by passing same connection string new MySqlDistributedSynchronizationProvider(connectionString)
I also tried without ProvidePasswordCallback, that is also not working.
Code:
services.AddScoped<IDistributedLockProvider>(serviceProvider =>
{
var connection = new MySqlConnection(connectionString) // this is not included password
{
ProvidePasswordCallback = conn =>
{
return accessToken; // password
},
};
return new MySqlDistributedSynchronizationProvider(connection);
});
Error:
System.InvalidOperationException: The connection and/or transaction are disposed or closed
at Medallion.Threading.Internal.Data.DedicatedConnectionOrTransactionDbDistributedLock.TryAcquireAsync[TLockCookie](TimeoutValue timeout, IDbSynchronizationStrategy`1 strategy, CancellationToken cancellationToken, IDistributedSynchronizationHandle contextHandle) in /_/src/DistributedLock.Core/Internal/Data/DedicatedConnectionOrTransactionDbDistributedLock.cs:line 66
at Medallion.Threading.Internal.Data.DedicatedConnectionOrTransactionDbDistributedLock.TryAcquireAsync[TLockCookie](TimeoutValue timeout, IDbSynchronizationStrategy`1 strategy, CancellationToken cancellationToken, IDistributedSynchronizationHandle contextHandle) in /_/src/DistributedLock.Core/Internal/Data/DedicatedConnectionOrTransactionDbDistributedLock.cs:line 94
at Medallion.Threading.Internal.DistributedLockHelpers.Wrap[THandle](ValueTask`1 handleTask, Func`2 factory) in /_/src/DistributedLock.Core/Internal/DistributedLockHelpers.cs:line 38
at Medallion.Threading.Internal.Helpers.Convert[TDerived,TBase](ValueTask`1 task, ValueTaskConversion _) in /_/src/DistributedLock.Core/Internal/Helpers.cs:line 22.
Versions: DistributedLock.MySql: 1.0.2 MySql server: 8.0.23 Dotnet : 8 MySqlConnector: 2.4.0
@jeyamaal the reason to construct a lock around a particular connection instance is so that you can ensure the lock is acquired on that specific connection. Here, you're passing a closed connection. Currently, DistributedLock does not open "externally owned" connections that are passed in (I suppose we could implement "open if needed and close if opened" behavior like EntityFramework; I haven't given it much thought).
Anyway, what you're doing should work if you open the connection before attempting to acquire the lock.
I'm curious: what is your use-case for not simply using a connection string?
@madelson , I need the providePasswordCallback approach, since I'm using token-based authentication with AWS RDS IAM. It helps effectively manage connection pooling, as token-based authentication creates a new connection string after a certain time period.
Refer: https://mysqlconnector.net/api/mysqlconnector/mysqlconnection/providepasswordcallback/
Thanks for the context @jeyamaal that makes sense.
As I mentioned, the current workaround is to open the connection yourself before attempting to acquire the lock (or equivalently construct the lock/provider using an already-opened connection).
If you are interested in contributing, an option could be to add support for a constructor that uses DbDataSource. This would let you leverage the password callback via this API.
You can see this commit where someone contributed that functionality for Postgres; the actual change set is really quite simple and small.
Let me know if making such a contribution interests you; otherwise I'll put this on the backlog.