Skip to content

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

Open

Description

@jeyamaal

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

Activity

  1. changed the title [-]Unable to create MySqlDistributedSynchronizationProvider by using MySqlConnection by using "ProvidePasswordCallback"[/-] [+]Unable to create MySqlDistributedSynchronizationProvider by using MySqlConnection via"ProvidePasswordCallback"[/+] on Jan 24, 2025
  2. madelson commented on Jan 25, 2025

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

  3. jeyamaal commented on Jan 25, 2025

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

  4. madelson commented on Jan 26, 2025

    @madelson
    Owner

    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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions