github.com/GeniusesGroup/libgo@v0.0.0-20220929090155-5ff932cb408e/tcp/stream-timing-keep_alive.go (about)

     1  /* For license and copyright information please see the LEGAL file in the code repository */
     2  
     3  package tcp
     4  
     5  import (
     6  	"github.com/GeniusesGroup/libgo/protocol"
     7  	"github.com/GeniusesGroup/libgo/time/monotonic"
     8  )
     9  
    10  type keepAlive struct {
    11  	enable     bool
    12  	idle       protocol.Duration
    13  	interval   protocol.Duration
    14  	lastUse    monotonic.Time
    15  	nextCheck  monotonic.Time
    16  	retryCount int
    17  }
    18  
    19  func (ka *keepAlive) Init(now monotonic.Time) (next protocol.Duration) {
    20  	ka.enable = true
    21  	ka.idle = KeepAlive_Idle
    22  	ka.interval = KeepAlive_Interval
    23  	now.Add(KeepAlive_Interval)
    24  	ka.nextCheck = now
    25  	return KeepAlive_Interval
    26  }
    27  func (ka *keepAlive) Reinit() {
    28  	ka.enable = false
    29  	ka.interval = 0
    30  	ka.nextCheck = 0
    31  	ka.retryCount = 0
    32  }
    33  func (ka *keepAlive) Deinit() {}
    34  
    35  // Don't block the caller
    36  func (ka *keepAlive) CheckInterval(st *Stream, now monotonic.Time) (next protocol.Duration) {
    37  	if !ka.enable {
    38  		return -1
    39  	}
    40  
    41  	// TODO::: check stream state
    42  
    43  	// check last use of stream and compare with our state
    44  	if ka.lastUse != st.lastUse {
    45  		ka.lastUse = st.lastUse
    46  		now.Add(ka.idle)
    47  		ka.nextCheck = now
    48  		ka.retryCount = 0
    49  		next = ka.idle
    50  		return
    51  	}
    52  
    53  	next = ka.next(now)
    54  	if next > 0 {
    55  		return
    56  	}
    57  	if next < 0 {
    58  		// calculate timer delta because timer start after nextCheck.
    59  		if ka.retryCount == 0 {
    60  			next = ka.idle + next // + because we have negative next
    61  		} else {
    62  			next = ka.interval + next // + because we have negative next
    63  		}
    64  	}
    65  	ka.nextCheck.Add(next)
    66  
    67  	// if (tp->packets_out || !tcp_write_queue_empty(sk))
    68  
    69  	if ka.retryCount <= KeepAlive_Probes {
    70  		// TODO::: send ack segment (keepalive message)
    71  		ka.retryCount++
    72  	} else {
    73  		// TODO::: kill the stream
    74  		// return
    75  	}
    76  	return
    77  }
    78  
    79  // d can be negative that show ka.CheckInterval called with some delay
    80  func (ka *keepAlive) next(now monotonic.Time) (d protocol.Duration) {
    81  	d = ka.nextCheck.Until(now)
    82  	return
    83  }