@@ -104,10 +104,7 @@ public async ValueTask<ServerSession> GetSessionAsync(MySqlConnection connection
104
104
}
105
105
106
106
// create a new session
107
- session = new ( this , m_generation , Interlocked . Increment ( ref m_lastSessionId ) ) ;
108
- if ( Log . IsInfoEnabled ( ) )
109
- Log . Info ( "Pool{0} no pooled session available; created new Session{1}" , m_logArguments [ 0 ] , session . Id ) ;
110
- await session . ConnectAsync ( ConnectionSettings , startTickCount , m_loadBalancer , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
107
+ session = await ConnectSessionAsync ( "Pool{0} no pooled session available; created new Session{1}" , startTickCount , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
111
108
AdjustHostConnectionCount ( session , 1 ) ;
112
109
session . OwningConnection = new ( connection ) ;
113
110
int leasedSessionsCountNew ;
@@ -350,9 +347,7 @@ private async Task CreateMinimumPooledSessions(IOBehavior ioBehavior, Cancellati
350
347
351
348
try
352
349
{
353
- var session = new ServerSession ( this , m_generation , Interlocked . Increment ( ref m_lastSessionId ) ) ;
354
- Log . Info ( "Pool{0} created Session{1} to reach minimum pool size" , m_logArguments [ 0 ] , session . Id ) ;
355
- await session . ConnectAsync ( ConnectionSettings , Environment . TickCount , m_loadBalancer , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
350
+ var session = await ConnectSessionAsync ( "Pool{0} created Session{1} to reach minimum pool size" , Environment . TickCount , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
356
351
AdjustHostConnectionCount ( session , 1 ) ;
357
352
lock ( m_sessions )
358
353
m_sessions . AddFirst ( session ) ;
@@ -365,6 +360,42 @@ private async Task CreateMinimumPooledSessions(IOBehavior ioBehavior, Cancellati
365
360
}
366
361
}
367
362
363
+ private async ValueTask < ServerSession > ConnectSessionAsync ( string logMessage , int startTickCount , IOBehavior ioBehavior , CancellationToken cancellationToken )
364
+ {
365
+ var session = new ServerSession ( this , m_generation , Interlocked . Increment ( ref m_lastSessionId ) ) ;
366
+ if ( Log . IsInfoEnabled ( ) )
367
+ Log . Info ( logMessage , m_logArguments [ 0 ] , session . Id ) ;
368
+ var statusInfo = await session . ConnectAsync ( ConnectionSettings , startTickCount , m_loadBalancer , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
369
+
370
+ if ( statusInfo is not null && statusInfo . StartsWith ( "Location: mysql://" , StringComparison . Ordinal ) )
371
+ {
372
+ // server redirection string has the format "Location: mysql://{host}:{port}/user={userId}[&ttl={ttl}]"
373
+ Log . Info ( "Session{0} has server redirection header {1}" , session . Id , statusInfo ) ;
374
+
375
+ if ( Utility . TryParseRedirectionHeader ( statusInfo , out var host , out var port , out var user ) )
376
+ {
377
+ Log . Info ( "Session{0} found server redirection Host={1}; Port={2}; User={3}" , session . Id , host , port , user ) ;
378
+
379
+ if ( host != ConnectionSettings . HostNames ! [ 0 ] || port != ConnectionSettings . Port || user != ConnectionSettings . UserID )
380
+ {
381
+ var redirectedSettings = ConnectionSettings . CloneWith ( host , port , user ) ;
382
+ Log . Info ( "Pool{0} opening new connection to Host={1}; Port={2}; User={3}" , m_logArguments [ 0 ] , host , port , user ) ;
383
+ var redirectedSession = new ServerSession ( this , m_generation , Interlocked . Increment ( ref m_lastSessionId ) ) ;
384
+ await redirectedSession . ConnectAsync ( redirectedSettings , startTickCount , m_loadBalancer , ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
385
+ Log . Info ( "Pool{0} closing Session{1} to use redirected Session{2} instead" , m_logArguments [ 0 ] , session . Id , redirectedSession . Id ) ;
386
+ await session . DisposeAsync ( ioBehavior , cancellationToken ) . ConfigureAwait ( false ) ;
387
+ return redirectedSession ;
388
+ }
389
+ else
390
+ {
391
+ Log . Info ( "Session{0} is already connected to this server; ignoring redirection" , session . Id ) ;
392
+ }
393
+ }
394
+ }
395
+
396
+ return session ;
397
+ }
398
+
368
399
public static ConnectionPool ? GetPool ( string connectionString )
369
400
{
370
401
// check single-entry MRU cache for this exact connection string; most applications have just one
0 commit comments