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

Method tryEnterIdleMode

internal/idle/idle.go:150–185  ·  view source on GitHub ↗

tryEnterIdleMode instructs the channel to enter idle mode. But before that, it performs a last minute check to ensure that no new RPC has come in, making the channel active. checkActivity controls if a check for RPC activity, since the last time the idle_timeout fired, is made. Return value indicat

(checkActivity bool)

Source from the content-addressed store, hash-verified

148//
149// Holds idleMu which ensures mutual exclusion with exitIdleMode.
150func (m *Manager) tryEnterIdleMode(checkActivity bool) bool {
151 // Setting the activeCallsCount to -math.MaxInt32 indicates to OnCallBegin()
152 // that the channel is either in idle mode or is trying to get there.
153 if !atomic.CompareAndSwapInt32(&m.activeCallsCount, 0, -math.MaxInt32) {
154 // This CAS operation can fail if an RPC started after we checked for
155 // activity in the timer handler, or one was ongoing from before the
156 // last time the timer fired, or if a test is attempting to enter idle
157 // mode without checking. In all cases, abort going into idle mode.
158 return false
159 }
160 // N.B. if we fail to enter idle mode after this, we must re-add
161 // math.MaxInt32 to m.activeCallsCount.
162
163 m.idleMu.Lock()
164 defer m.idleMu.Unlock()
165
166 if atomic.LoadInt32(&m.activeCallsCount) != -math.MaxInt32 {
167 // We raced and lost to a new RPC. Very rare, but stop entering idle.
168 atomic.AddInt32(&m.activeCallsCount, math.MaxInt32)
169 return false
170 }
171 if checkActivity && atomic.LoadInt32(&m.activeSinceLastTimerCheck) == 1 {
172 // A very short RPC could have come in (and also finished) after we
173 // checked for calls count and activity in handleIdleTimeout(), but
174 // before the CAS operation. So, we need to check for activity again.
175 atomic.AddInt32(&m.activeCallsCount, math.MaxInt32)
176 return false
177 }
178
179 // No new RPCs have come in since we set the active calls count value to
180 // -math.MaxInt32. And since we have the lock, it is safe to enter idle mode
181 // unconditionally now.
182 m.cc.EnterIdleMode()
183 m.actuallyIdle = true
184 return true
185}
186
187// EnterIdleModeForTesting instructs the channel to enter idle mode.
188func (m *Manager) EnterIdleModeForTesting() {

Callers 2

handleIdleTimeoutMethod · 0.95

Calls 3

EnterIdleModeMethod · 0.65
LockMethod · 0.45
UnlockMethod · 0.45

Tested by

no test coverage detected