@@ -18,6 +18,11 @@ import (
1818 "context"
1919 "encoding/hex"
2020 "fmt"
21+ << << << < HEAD
22+ == == == =
23+ "maps"
24+ "slices"
25+ >> >> >> > 69e8 fdb60b5 (timer : make sure timer which has a max delay will be scheduled first (#57067 ))
2126 "sync"
2227 "time"
2328
@@ -241,9 +246,7 @@ func (rt *TimerGroupRuntime) fullRefreshTimers() {
241246
242247func (rt * TimerGroupRuntime ) tryTriggerTimerEvents () {
243248 now := rt .nowFunc ()
244- var retryTimerIDs []string
245- var retryTimerKeys []string
246- var busyWorkers map [string ]struct {}
249+ var readyTimers []* timerCacheItem
247250 rt .cache .iterTryTriggerTimers (func (timer * api.TimerRecord , tryTriggerTime time.Time , nextEventTime * time.Time ) bool {
248251 if tryTriggerTime .After (now ) {
249252 return false
@@ -253,9 +256,45 @@ func (rt *TimerGroupRuntime) tryTriggerTimerEvents() {
253256 return true
254257 }
255258
259+ if readyTimers == nil {
260+ readyTimers = make ([]* timerCacheItem , 0 , 8 )
261+ }
262+
263+ readyTimers = append (readyTimers , & timerCacheItem {
264+ timer : timer ,
265+ nextEventTime : nextEventTime ,
266+ })
267+ return true
268+ })
269+
270+ if len (readyTimers ) == 0 {
271+ return
272+ }
273+
274+ // resort timer to make sure the timer has the smallest nextEventTime has a higher priority to trigger
275+ slices .SortFunc (readyTimers , func (a , b * timerCacheItem ) int {
276+ if a .nextEventTime == nil || b .nextEventTime == nil {
277+ if a .nextEventTime != nil {
278+ return 1
279+ }
280+
281+ if b .nextEventTime != nil {
282+ return - 1
283+ }
284+
285+ return 0
286+ }
287+ return a .nextEventTime .Compare (* b .nextEventTime )
288+ })
289+
290+ var retryTimerIDs []string
291+ var retryTimerKeys []string
292+ var busyWorkers map [string ]struct {}
293+ for i , item := range readyTimers {
294+ timer := item .timer
256295 worker , ok := rt .ensureWorker (timer .HookClass )
257296 if ! ok {
258- return true
297+ continue
259298 }
260299
261300 eventID := timer .EventID
@@ -273,20 +312,22 @@ func (rt *TimerGroupRuntime) tryTriggerTimerEvents() {
273312
274313 select {
275314 case <- rt .ctx .Done ():
276- return false
315+ return
277316 case worker .ch <- req :
278317 rt .cache .setTimerProcStatus (timer .ID , procTriggering , eventID )
279318 default :
280319 if busyWorkers == nil {
281- busyWorkers = make (map [string ]struct {})
320+ busySize := len (readyTimers ) - i
321+ retryTimerIDs = make ([]string , 0 , busySize )
322+ retryTimerKeys = make ([]string , 0 , busySize )
323+ busyWorkers = make (map [string ]struct {}, busySize )
282324 }
283325
284326 busyWorkers [timer .HookClass ] = struct {}{}
285327 retryTimerIDs = append (retryTimerIDs , timer .ID )
286328 retryTimerKeys = append (retryTimerKeys , fmt .Sprintf ("[%s] %s" , timer .Namespace , timer .Key ))
287329 }
288- return true
289- })
330+ }
290331
291332 if len (retryTimerIDs ) > 0 {
292333 busyWorkerList := make ([]string , 0 , len (busyWorkers ))
0 commit comments