@@ -35,7 +35,7 @@ func NewSchedule(redisClient *redis.Client) Schedule {
3535func (s * ScheduleImpl ) Add (ctx context.Context , task * Task ) error {
3636 // Marshal the task data
3737
38- payload , err := json .Marshal (TaskData {
38+ taskData , err := json .Marshal (TaskData {
3939 Interval : task .Interval / time .Millisecond ,
4040 Data : task .Data ,
4141 })
@@ -53,12 +53,12 @@ func (s *ScheduleImpl) Add(ctx context.Context, task *Task) error {
5353
5454 script := redis .NewScript (`
5555 local queueKey = KEYS[1]
56- local payloadKey = KEYS[2]
56+ local taskDataKey = KEYS[2]
5757 local id = ARGV[1]
58- local payload = ARGV[2]
58+ local taskData = ARGV[2]
5959 local score = ARGV[3]
6060
61- redis.call("HSETNX", payloadKey , id, payload )
61+ redis.call("HSETNX", taskDataKey , id, taskData )
6262 redis.call("ZADD", queueKey, score, id)
6363
6464 return 1
@@ -72,7 +72,7 @@ func (s *ScheduleImpl) Add(ctx context.Context, task *Task) error {
7272 s .taskDataKey (task .Kind ),
7373 },
7474 task .ID ,
75- payload ,
75+ taskData ,
7676 float64 (nextTick ),
7777 ).Err (); err != nil {
7878 return err
@@ -86,10 +86,10 @@ func (s *ScheduleImpl) Remove(ctx context.Context, kind string, id string) error
8686
8787 script := redis .NewScript (`
8888 local queueKey = KEYS[1]
89- local payloadKey = KEYS[2]
89+ local taskDataKey = KEYS[2]
9090 local id = ARGV[1]
9191
92- redis.call("HDEL", payloadKey , id)
92+ redis.call("HDEL", taskDataKey , id)
9393 redis.call("ZREM", queueKey, id)
9494
9595 return 1
@@ -147,6 +147,8 @@ func (s *ScheduleImpl) On(ctx context.Context, kind string, handler func(ctx con
147147
148148 local now = tonumber(ARGV[1])
149149
150+ -- Pop the next task from the queue
151+
150152 local res = redis.call("ZPOPMIN", queueKey)
151153 if #res == 0 then
152154 return { -1 }
@@ -155,11 +157,15 @@ func (s *ScheduleImpl) On(ctx context.Context, kind string, handler func(ctx con
155157 local id = res[1]
156158 local score = tonumber(res[2])
157159
160+ -- If the task is scheduled for more than 1 second in the future, put it back in the queue
161+
158162 if score > (now + 1000) then
159163 redis.call("ZADD", queueKey, score, id)
160164 return { -1 }
161165 end
162166
167+ -- Get the task data
168+
163169 local taskDataRaw = redis.call("HGET", taskDataKey, id)
164170 if taskDataRaw == nil then
165171 return { -1 }
@@ -170,8 +176,19 @@ func (s *ScheduleImpl) On(ctx context.Context, kind string, handler func(ctx con
170176 return { -1 }
171177 end
172178
179+ -- Schedule the next execution
180+
173181 local nextTick = score + taskData.Interval
174182
183+ -- If the next execution is in the past, schedule it for the next interval
184+ if nextTick < now then
185+ -- Find how many intervals have passed since the last execution
186+ local intervals = math.floor((now - score) / taskData.Interval)
187+
188+ -- Schedule the next execution for the next interval
189+ nextTick = score + (intervals * taskData.Interval) + taskData.Interval
190+ end
191+
175192 redis.call("ZADD", queueKey, nextTick, id)
176193
177194 return {id, score, taskDataRaw}
0 commit comments