Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to create MySqlDistributedSynchronizationProvider by using MySqlConnection via"ProvidePasswordCallback" #237

Open
jeyamaal opened this issue Jan 24, 2025 · 3 comments

Comments

@jeyamaal
Copy link

jeyamaal commented Jan 24, 2025

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 jeyamaal changed the title Unable to create MySqlDistributedSynchronizationProvider by using MySqlConnection by using "ProvidePasswordCallback" Unable to create MySqlDistributedSynchronizationProvider by using MySqlConnection via"ProvidePasswordCallback" Jan 24, 2025
@madelson
Copy link
Owner

@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?

@jeyamaal
Copy link
Author

@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/

@madelson
Copy link
Owner

madelson commented Jan 26, 2025

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants