MCPcopy
hub / github.com/grpc/grpc-go / keepalive

Method keepalive

internal/transport/http2_server.go:1187–1276  ·  view source on GitHub ↗

keepalive running in a separate goroutine does the following: 1. Gracefully closes an idle connection after a duration of keepalive.MaxConnectionIdle. 2. Gracefully closes any connection after a duration of keepalive.MaxConnectionAge. 3. Forcibly closes a connection after an additive period of keepa

()

Source from the content-addressed store, hash-verified

1185// 4. Makes sure a connection is alive by sending pings with a frequency of keepalive.Time and closes a non-responsive connection
1186// after an additional duration of keepalive.Timeout.
1187func (t *http2Server) keepalive() {
1188 p := &ping{}
1189 // True iff a ping has been sent, and no data has been received since then.
1190 outstandingPing := false
1191 // Amount of time remaining before which we should receive an ACK for the
1192 // last sent ping.
1193 kpTimeoutLeft := time.Duration(0)
1194 // Records the last value of t.lastRead before we go block on the timer.
1195 // This is required to check for read activity since then.
1196 prevNano := time.Now().UnixNano()
1197 // Initialize the different timers to their default values.
1198 idleTimer := time.NewTimer(t.kp.MaxConnectionIdle)
1199 ageTimer := time.NewTimer(t.kp.MaxConnectionAge)
1200 kpTimer := time.NewTimer(t.kp.Time)
1201 defer func() {
1202 // We need to drain the underlying channel in these timers after a call
1203 // to Stop(), only if we are interested in resetting them. Clearly we
1204 // are not interested in resetting them here.
1205 idleTimer.Stop()
1206 ageTimer.Stop()
1207 kpTimer.Stop()
1208 }()
1209
1210 for {
1211 select {
1212 case <-idleTimer.C:
1213 t.mu.Lock()
1214 idle := t.idle
1215 if idle.IsZero() { // The connection is non-idle.
1216 t.mu.Unlock()
1217 idleTimer.Reset(t.kp.MaxConnectionIdle)
1218 continue
1219 }
1220 val := t.kp.MaxConnectionIdle - time.Since(idle)
1221 t.mu.Unlock()
1222 if val <= 0 {
1223 // The connection has been idle for a duration of keepalive.MaxConnectionIdle or more.
1224 // Gracefully close the connection.
1225 t.Drain("max_idle")
1226 return
1227 }
1228 idleTimer.Reset(val)
1229 case <-ageTimer.C:
1230 t.Drain("max_age")
1231 ageTimer.Reset(t.kp.MaxConnectionAgeGrace)
1232 select {
1233 case <-ageTimer.C:
1234 // Close the connection after grace period.
1235 if t.logger.V(logLevel) {
1236 t.logger.Infof("Closing server transport due to maximum connection age")
1237 }
1238 t.controlBuf.put(closeConnection{})
1239 case <-t.done:
1240 }
1241 return
1242 case <-kpTimer.C:
1243 lastRead := atomic.LoadInt64(&t.lastRead)
1244 if lastRead > prevNano {

Callers 1

NewServerTransportFunction · 0.95

Calls 14

StopMethod · 0.95
ResetMethod · 0.95
DrainMethod · 0.95
CloseMethod · 0.95
IsOnFunction · 0.92
NowMethod · 0.80
NewTimerMethod · 0.80
VMethod · 0.65
InfofMethod · 0.65
ErrorfMethod · 0.65
AddMethod · 0.65
LockMethod · 0.45

Tested by

no test coverage detected