internal async Task OpenAsync()

in MySQL.Data/src/MySqlConnection.cs [600:720]


    internal async Task OpenAsync(bool execAsync, CancellationToken cancellationToken)
    {
      if (State != ConnectionState.Closed)
        Throw(new InvalidOperationException(Resources.ConnectionAlreadyOpen));

      if (hasBeenDisposed)
        Throw(new InvalidOperationException("The connection had been disposed."));

      // start up our interceptors
      _exceptionInterceptor = new ExceptionInterceptor(this);
      commandInterceptor = new CommandInterceptor(this);

      SetState(ConnectionState.Connecting, true);
      AssertPermissions();

      Settings.WebAuthnActionRequested = WebAuthnActionRequested;

      //TODO: SUPPORT FOR 452 AND 46X
      // if we are auto enlisting in a current transaction, then we will be
      // treating the connection as pooled
      if (Settings.AutoEnlist && Transaction.Current != null)
      {
        driver = DriverTransactionManager.GetDriverInTransaction(Transaction.Current);
        if (driver != null && (driver.IsInActiveUse || !driver.Settings.EquivalentTo(this.Settings)))
          Throw(new NotSupportedException(Resources.MultipleConnectionsInTransactionNotSupported));
      }

      MySqlConnectionStringBuilder currentSettings = Settings;
      try
      {
        if (!Settings.Pooling || MySqlPoolManager.Hosts == null)
        {
          FailoverManager.Reset();

          if (Settings.DnsSrv)
          {
            var dnsSrvRecords = DnsSrv.GetDnsSrvRecords(Settings.Server);
            FailoverManager.SetHostList(dnsSrvRecords.ConvertAll(r => new FailoverServer(r.Target, r.Port, null)),
              FailoverMethod.Sequential);
          }
          else
            FailoverManager.ParseHostList(Settings.Server, false);
        }

        // Load balancing && Failover
        if (ReplicationManager.IsReplicationGroup(Settings.Server))
        {
          if (driver == null)
          {
            await ReplicationManager.GetNewConnectionAsync(Settings.Server, false, this, execAsync, cancellationToken).ConfigureAwait(false);
          }
          else
            currentSettings = driver.Settings;
        }
        else if (FailoverManager.FailoverGroup != null && !Settings.Pooling)
        {
          string connectionString = await FailoverManager.AttemptConnectionAsync(this, Settings.ConnectionString, execAsync, cancellationToken);
          currentSettings.ConnectionString = connectionString;
        }

        if (Settings.Pooling)
        {
          if (FailoverManager.FailoverGroup != null)
          {
            string connectionString = await FailoverManager.AttemptConnectionAsync(this, Settings.ConnectionString, execAsync, cancellationToken, true);
            currentSettings.ConnectionString = connectionString;
          }
#if NET5_0_OR_GREATER              
          currentActivity = MySQLActivitySource.OpenPooledConnection(currentSettings);
#endif
          MySqlPool pool = await MySqlPoolManager.GetPoolAsync(currentSettings, execAsync, cancellationToken).ConfigureAwait(false);
          if (driver == null || !driver.IsOpen)
            driver = await pool.GetConnectionAsync(execAsync, cancellationToken).ConfigureAwait(false);
          ProcedureCache = pool.ProcedureCache;
        }
        else
        {
            if (driver == null || !driver.IsOpen)
            {
#if NET5_0_OR_GREATER              
                currentActivity = MySQLActivitySource.OpenConnection(currentSettings);
#endif
                driver = await Driver.CreateAsync(currentSettings, execAsync, cancellationToken).ConfigureAwait(false);
            }

            ProcedureCache = new ProcedureCache((int)Settings.ProcedureCacheSize);
        }
      }
      catch (Exception ex)
      {
#if NET5_0_OR_GREATER              
        MySQLActivitySource.SetException(currentActivity, ex);
#endif
        SetState(ConnectionState.Closed, true);
        throw;
      }

      SetState(ConnectionState.Open, false);
      await driver.ConfigureAsync(this, execAsync, cancellationToken).ConfigureAwait(false);

      if (driver.IsPasswordExpired && Settings.Pooling)
        await MySqlPoolManager.ClearPoolAsync(currentSettings, execAsync).ConfigureAwait(false);

      if (!(driver.SupportsPasswordExpiration && driver.IsPasswordExpired))
      {
        if (!string.IsNullOrEmpty(Settings.Database))
          await ChangeDatabaseAsync(Settings.Database, execAsync, cancellationToken).ConfigureAwait(false);
      }

      // setup our schema provider
      _schemaProvider = new ISSchemaProvider(this);
      PerfMonitor = new PerformanceMonitor(this);

      // if we are opening up inside a current transaction, then autoenlist
      // TODO: control this with a connection string option
      if (Transaction.Current != null && Settings.AutoEnlist)
        EnlistTransaction(Transaction.Current);

      hasBeenOpen = true;
      SetState(ConnectionState.Open, true);
    }