getEffectiveWriteTimeout returns the timeout to use for write operations. If relaxed timeout is set and not expired, it takes precedence over the provided timeout. This method automatically clears expired relaxed timeouts using atomic operations.
(normalTimeout time.Duration)
| 569 | // If relaxed timeout is set and not expired, it takes precedence over the provided timeout. |
| 570 | // This method automatically clears expired relaxed timeouts using atomic operations. |
| 571 | func (cn *Conn) getEffectiveWriteTimeout(normalTimeout time.Duration) time.Duration { |
| 572 | writeTimeoutNs := cn.relaxedWriteTimeoutNs.Load() |
| 573 | |
| 574 | // Fast path: no relaxed timeout set |
| 575 | if writeTimeoutNs <= 0 { |
| 576 | return normalTimeout |
| 577 | } |
| 578 | |
| 579 | deadlineNs := cn.relaxedDeadlineNs.Load() |
| 580 | // If no deadline is set, use relaxed timeout |
| 581 | if deadlineNs == 0 { |
| 582 | return time.Duration(writeTimeoutNs) |
| 583 | } |
| 584 | |
| 585 | // Use cached time to avoid expensive syscall (max 50ms staleness is acceptable for timeout checks) |
| 586 | nowNs := getCachedTimeNs() |
| 587 | // Check if deadline has passed |
| 588 | if nowNs < deadlineNs { |
| 589 | // Deadline is in the future, use relaxed timeout |
| 590 | return time.Duration(writeTimeoutNs) |
| 591 | } else { |
| 592 | // Deadline has passed, clear relaxed timeouts atomically and use normal timeout |
| 593 | newCount := cn.relaxedCounter.Add(-1) |
| 594 | if newCount <= 0 { |
| 595 | internal.Logger.Printf(context.Background(), logs.UnrelaxedTimeoutAfterDeadline(cn.GetID())) |
| 596 | cn.clearRelaxedTimeout() |
| 597 | } |
| 598 | return normalTimeout |
| 599 | } |
| 600 | } |
| 601 | |
| 602 | // SetOnClose installs fn as the callback invoked exactly once when this |
| 603 | // connection is closed (via Conn.Close). |
no test coverage detected