@@ -217,7 +217,7 @@ func (ph *PoolHook) onDemandWorker() {
217217
218218 case <- time .After (ph .workerTimeout ):
219219 // Worker has been idle for too long, exit to save resources
220- if ph .config != nil && ph .config .LogLevel >= 3 { // Debug level
220+ if ph .config != nil && ph .config .LogLevel >= LogLevelDebug { // Debug level
221221 internal .Logger .Printf (context .Background (),
222222 "hitless: worker exiting due to inactivity timeout (%v)" , ph .workerTimeout )
223223 }
@@ -258,6 +258,7 @@ func (ph *PoolHook) processHandoffRequest(request HandoffRequest) {
258258
259259 // Perform the handoff with cancellable context
260260 shouldRetry , err := ph .performConnectionHandoffWithPool (shutdownCtx , request .Conn , request .Pool )
261+ minRetryBackoff := 500 * time .Millisecond
261262 if err != nil {
262263 if shouldRetry {
263264 now := time .Now ()
@@ -268,20 +269,31 @@ func (ph *PoolHook) processHandoffRequest(request HandoffRequest) {
268269 }
269270
270271 afterTime := deadline .Sub (now )
271- if afterTime < handoffTimeout / 2 {
272+ if afterTime > handoffTimeout / 2 {
272273 afterTime = handoffTimeout / 2
273274 }
275+ if afterTime < minRetryBackoff {
276+ afterTime = minRetryBackoff
277+ }
274278
275279 internal .Logger .Printf (context .Background (), "Handoff failed for conn[%d] WILL RETRY After %v: %v" , request .ConnID , afterTime , err )
276280 time .AfterFunc (afterTime , func () {
277281 if err := ph .queueHandoff (request .Conn ); err != nil {
278282 internal .Logger .Printf (context .Background (), "can't queue handoff for retry: %v" , err )
279- ph .removeConn (ctx , request , err )
283+ ph .removeConn (context . Background () , request , err )
280284 }
281285 })
286+ return
282287 } else {
283288 go ph .removeConn (ctx , request , err )
284289 }
290+
291+ // Clear handoff state if not returned for retry
292+ seqID := request .Conn .GetMovingSeqID ()
293+ connID := request .Conn .GetID ()
294+ if ph .hitlessManager != nil {
295+ ph .hitlessManager .UntrackOperationWithConnID (seqID , connID )
296+ }
285297 }
286298}
287299
@@ -290,14 +302,14 @@ func (ph *PoolHook) removeConn(ctx context.Context, request HandoffRequest, err
290302 conn := request .Conn
291303 if pooler != nil {
292304 pooler .Remove (ctx , conn , err )
293- if ph .config != nil && ph .config .LogLevel >= 1 { // Warning level
305+ if ph .config != nil && ph .config .LogLevel >= LogLevelWarn { // Warning level
294306 internal .Logger .Printf (ctx ,
295307 "hitless: removed connection %d from pool due to max handoff retries reached" ,
296308 conn .GetID ())
297309 }
298310 } else {
299311 conn .Close ()
300- if ph .config != nil && ph .config .LogLevel >= 1 { // Warning level
312+ if ph .config != nil && ph .config .LogLevel >= LogLevelWarn { // Warning level
301313 internal .Logger .Printf (ctx ,
302314 "hitless: no pool provided for connection %d, cannot remove due to handoff initialization failure: %v" ,
303315 conn .GetID (), err )
@@ -335,7 +347,7 @@ func (ph *PoolHook) queueHandoff(conn *pool.Conn) error {
335347 // Queue is full - log and attempt scaling
336348 queueLen := len (ph .handoffQueue )
337349 queueCap := cap (ph .handoffQueue )
338- if ph .config != nil && ph .config .LogLevel >= 1 { // Warning level
350+ if ph .config != nil && ph .config .LogLevel >= LogLevelWarn { // Warning level
339351 internal .Logger .Printf (context .Background (),
340352 "hitless: handoff queue is full (%d/%d), attempting timeout queuing and scaling workers" ,
341353 queueLen , queueCap )
@@ -352,14 +364,8 @@ func (ph *PoolHook) queueHandoff(conn *pool.Conn) error {
352364// When error is returned, the connection handoff should be retried if err is not ErrMaxHandoffRetriesReached
353365func (ph * PoolHook ) performConnectionHandoffWithPool (ctx context.Context , conn * pool.Conn , pooler pool.Pooler ) (shouldRetry bool , err error ) {
354366 // Clear handoff state after successful handoff
355- seqID := conn .GetMovingSeqID ()
356367 connID := conn .GetID ()
357368
358- // Notify hitless manager of completion if available
359- if ph .hitlessManager != nil {
360- defer ph .hitlessManager .UntrackOperationWithConnID (seqID , connID )
361- }
362-
363369 newEndpoint := conn .GetHandoffEndpoint ()
364370 if newEndpoint == "" {
365371 return false , ErrConnectionInvalidHandoffState
@@ -373,7 +379,7 @@ func (ph *PoolHook) performConnectionHandoffWithPool(ctx context.Context, conn *
373379 }
374380
375381 if retries > maxRetries {
376- if ph .config != nil && ph .config .LogLevel >= 1 { // Warning level
382+ if ph .config != nil && ph .config .LogLevel >= LogLevelWarn { // Warning level
377383 internal .Logger .Printf (ctx ,
378384 "hitless: reached max retries (%d) for handoff of connection %d to %s" ,
379385 maxRetries , conn .GetID (), conn .GetHandoffEndpoint ())
@@ -425,8 +431,8 @@ func (ph *PoolHook) performConnectionHandoffWithPool(ctx context.Context, conn *
425431
426432 if ph .config .LogLevel >= 2 { // Info level
427433 internal .Logger .Printf (context .Background (),
428- "hitless: applied post-handoff relaxed timeout (%v) until %v for connection %d " ,
429- relaxedTimeout , deadline .Format ("15:04:05.000" ), connID )
434+ "hitless: conn[%d] applied post-handoff relaxed timeout (%v) until %v" ,
435+ connID , relaxedTimeout , deadline .Format ("15:04:05.000" ))
430436 }
431437 }
432438
0 commit comments