@@ -179,40 +179,27 @@ func (r *ReAuthPoolHook) OnPut(_ context.Context, conn *pool.Conn) (bool, bool,
179179 r .workers <- struct {}{}
180180 }()
181181
182- var err error
183- timeout := time .After (r .reAuthTimeout )
182+ // Create timeout context for connection acquisition
183+ // This prevents indefinite waiting if the connection is stuck
184+ ctx , cancel := context .WithTimeout (context .Background (), r .reAuthTimeout )
185+ defer cancel ()
184186
185187 // Try to acquire the connection for re-authentication
186188 // We need to ensure the connection is IDLE (not IN_USE) before transitioning to UNUSABLE
187189 // This prevents re-authentication from interfering with active commands
188- const baseDelay = 10 * time .Microsecond
189- acquired := false
190- attempt := 0
191- for ! acquired {
192- select {
193- case <- timeout :
194- // Timeout occurred, cannot acquire connection
195- err = pool .ErrConnUnusableTimeout
196- reAuthFn (err )
197- return
198- default :
199- // Try to atomically transition from IDLE to UNUSABLE
200- // This ensures we only acquire connections that are not actively in use
201- stateMachine := conn .GetStateMachine ()
202- if stateMachine != nil {
203- _ , err := stateMachine .TryTransition ([]pool.ConnState {pool .StateIdle }, pool .StateUnusable )
204- if err == nil {
205- // Successfully acquired: connection was IDLE, now UNUSABLE
206- acquired = true
207- }
208- }
209- if ! acquired {
210- // Exponential backoff: 10, 20, 40, 80... up to 5120 microseconds
211- delay := baseDelay * time .Duration (1 << uint (attempt % 10 )) // Cap exponential growth
212- time .Sleep (delay )
213- attempt ++
214- }
215- }
190+ // Use AwaitAndTransition to wait for the connection to become IDLE
191+ stateMachine := conn .GetStateMachine ()
192+ if stateMachine == nil {
193+ // No state machine - should not happen, but handle gracefully
194+ reAuthFn (pool .ErrConnUnusableTimeout )
195+ return
196+ }
197+
198+ _ , err := stateMachine .AwaitAndTransition (ctx , []pool.ConnState {pool .StateIdle }, pool .StateUnusable )
199+ if err != nil {
200+ // Timeout or other error occurred, cannot acquire connection
201+ reAuthFn (err )
202+ return
216203 }
217204
218205 // safety first
@@ -222,10 +209,7 @@ func (r *ReAuthPoolHook) OnPut(_ context.Context, conn *pool.Conn) (bool, bool,
222209 }
223210
224211 // Release the connection: transition from UNUSABLE back to IDLE
225- stateMachine := conn .GetStateMachine ()
226- if stateMachine != nil {
227- stateMachine .Transition (pool .StateIdle )
228- }
212+ stateMachine .Transition (pool .StateIdle )
229213 }()
230214 }
231215
0 commit comments