88
99namespace MySqlConnector . Core ;
1010
11- internal sealed class ConnectionPool : IDisposable
11+ internal sealed class ConnectionPool : IConnectionPoolMetadata , IDisposable
1212{
1313 public int Id { get ; }
1414
15+ ConnectionPool ? IConnectionPoolMetadata . ConnectionPool => this ;
16+
17+ int IConnectionPoolMetadata . Generation => m_generation ;
18+
19+ int IConnectionPoolMetadata . GetNewSessionId ( ) => Interlocked . Increment ( ref m_lastSessionId ) ;
20+
1521 public string ? Name { get ; }
1622
1723 public ConnectionSettings ConnectionSettings { get ; }
@@ -95,6 +101,7 @@ public async ValueTask<ServerSession> GetSessionAsync(MySqlConnection connection
95101 m_leasedSessions . Add ( session . Id , session ) ;
96102 leasedSessionsCountPooled = m_leasedSessions . Count ;
97103 }
104+
98105 MetricsReporter . AddUsed ( this ) ;
99106 ActivitySourceHelper . CopyTags ( session . ActivityTags , activity ) ;
100107 Log . ReturningPooledSession ( m_logger , Id , session . Id , leasedSessionsCountPooled ) ;
@@ -106,7 +113,8 @@ public async ValueTask<ServerSession> GetSessionAsync(MySqlConnection connection
106113 }
107114
108115 // create a new session
109- session = await ConnectSessionAsync ( connection , s_createdNewSession , startingTimestamp , activity , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
116+ session = await ServerSession . ConnectAndRedirectAsync ( m_connectionLogger , m_logger , this , ConnectionSettings , m_loadBalancer ,
117+ connection , s_createdNewSession , startingTimestamp , activity , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
110118 AdjustHostConnectionCount ( session , 1 ) ;
111119 session . OwningConnection = new ( connection ) ;
112120 int leasedSessionsCountNew ;
@@ -402,7 +410,8 @@ private async Task CreateMinimumPooledSessions(MySqlConnection connection, IOBeh
402410
403411 try
404412 {
405- var session = await ConnectSessionAsync ( connection , s_createdToReachMinimumPoolSize , Stopwatch . GetTimestamp ( ) , null , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
413+ var session = await ServerSession . ConnectAndRedirectAsync ( m_connectionLogger , m_logger , this , ConnectionSettings , m_loadBalancer ,
414+ connection , s_createdToReachMinimumPoolSize , Stopwatch . GetTimestamp ( ) , null , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
406415 AdjustHostConnectionCount ( session , 1 ) ;
407416 lock ( m_sessions )
408417 _ = m_sessions . AddFirst ( session ) ;
@@ -416,81 +425,6 @@ private async Task CreateMinimumPooledSessions(MySqlConnection connection, IOBeh
416425 }
417426 }
418427
419- private async ValueTask < ServerSession > ConnectSessionAsync ( MySqlConnection connection , Action < ILogger , int , string , Exception ? > logMessage , long startingTimestamp , Activity ? activity , IOBehavior ioBehavior , CancellationToken cancellationToken )
420- {
421- var session = new ServerSession ( m_connectionLogger , this , m_generation , Interlocked . Increment ( ref m_lastSessionId ) ) ;
422- if ( m_logger . IsEnabled ( LogLevel . Debug ) )
423- logMessage ( m_logger , Id , session . Id , null ) ;
424- string ? statusInfo ;
425- try
426- {
427- statusInfo = await session . ConnectAsync ( ConnectionSettings , connection , startingTimestamp , m_loadBalancer , activity , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
428- }
429- catch ( Exception )
430- {
431- await session . DisposeAsync ( ioBehavior , default ) . ConfigureAwait ( false ) ;
432- throw ;
433- }
434-
435- Exception ? redirectionException = null ;
436- if ( statusInfo is not null && statusInfo . StartsWith ( "Location: mysql://" , StringComparison . Ordinal ) )
437- {
438- // server redirection string has the format "Location: mysql://{host}:{port}/user={userId}[&ttl={ttl}]"
439- Log . HasServerRedirectionHeader ( m_logger , session . Id , statusInfo ) ;
440-
441- if ( ConnectionSettings . ServerRedirectionMode == MySqlServerRedirectionMode . Disabled )
442- {
443- Log . ServerRedirectionIsDisabled ( m_logger , Id ) ;
444- }
445- else if ( Utility . TryParseRedirectionHeader ( statusInfo , out var host , out var port , out var user ) )
446- {
447- if ( host != ConnectionSettings . HostNames ! [ 0 ] || port != ConnectionSettings . Port || user != ConnectionSettings . UserID )
448- {
449- var redirectedSettings = ConnectionSettings . CloneWith ( host , port , user ) ;
450- Log . OpeningNewConnection ( m_logger , Id , host , port , user ) ;
451- var redirectedSession = new ServerSession ( m_connectionLogger , this , m_generation , Interlocked . Increment ( ref m_lastSessionId ) ) ;
452- try
453- {
454- _ = await redirectedSession . ConnectAsync ( redirectedSettings , connection , startingTimestamp , m_loadBalancer , activity , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
455- }
456- catch ( Exception ex )
457- {
458- Log . FailedToConnectRedirectedSession ( m_logger , ex , Id , redirectedSession . Id ) ;
459- redirectionException = ex ;
460- }
461-
462- if ( redirectionException is null )
463- {
464- Log . ClosingSessionToUseRedirectedSession ( m_logger , Id , session . Id , redirectedSession . Id ) ;
465- await session . DisposeAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
466- return redirectedSession ;
467- }
468- else
469- {
470- try
471- {
472- await redirectedSession . DisposeAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
473- }
474- catch ( Exception )
475- {
476- }
477- }
478- }
479- else
480- {
481- Log . SessionAlreadyConnectedToServer ( m_logger , session . Id ) ;
482- }
483- }
484- }
485-
486- if ( ConnectionSettings . ServerRedirectionMode == MySqlServerRedirectionMode . Required )
487- {
488- Log . RequiresServerRedirection ( m_logger , Id ) ;
489- throw new MySqlException ( MySqlErrorCode . UnableToConnectToHost , "Server does not support redirection" , redirectionException ) ;
490- }
491- return session ;
492- }
493-
494428 public static ConnectionPool ? CreatePool ( string connectionString , MySqlConnectorLoggingConfiguration loggingConfiguration , string ? name )
495429 {
496430 // parse connection string and check for 'Pooling' setting; return 'null' if pooling is disabled
0 commit comments