kick broadcasts to all idle poll workers. Safe to call from any goroutine. When adaptive coalescing is enabled (coalesceStep > 0) kicks within a burst are collapsed into a single delayed wake: the first kick arms a step-ms timer and records a hard deadline (now + coalesceMax); subsequent kicks rese
()
| 1317 | // stream of arrivals does not delay the wake past coalesceMax. When step |
| 1318 | // is 0 the wake fires immediately as before. |
| 1319 | func (c *Client) kick() { |
| 1320 | if c.coalesceStep <= 0 { |
| 1321 | c.wake.Broadcast() |
| 1322 | return |
| 1323 | } |
| 1324 | |
| 1325 | c.coalesceMu.Lock() |
| 1326 | defer c.coalesceMu.Unlock() |
| 1327 | |
| 1328 | now := time.Now() |
| 1329 | if c.coalesceTimer == nil { |
| 1330 | // First kick of a burst: set hard deadline and arm the step timer. |
| 1331 | c.coalesceDeadline = now.Add(c.coalesceMax) |
| 1332 | c.coalesceTimer = time.AfterFunc(c.coalesceStep, c.fireCoalesceWake) |
| 1333 | return |
| 1334 | } |
| 1335 | |
| 1336 | // Subsequent kick: extend the step timer, but never past the hard cap. |
| 1337 | nextFire := now.Add(c.coalesceStep) |
| 1338 | if nextFire.After(c.coalesceDeadline) { |
| 1339 | nextFire = c.coalesceDeadline |
| 1340 | } |
| 1341 | wait := nextFire.Sub(now) |
| 1342 | if wait <= 0 { |
| 1343 | // Already at or past the hard deadline — let the existing timer fire. |
| 1344 | return |
| 1345 | } |
| 1346 | c.coalesceTimer.Reset(wait) |
| 1347 | } |
| 1348 | |
| 1349 | // fireCoalesceWake clears the timer and broadcasts the wake. Called from |
| 1350 | // the time.AfterFunc goroutine when the coalesce window closes. |