Skip to content

Commit 6f67e52

Browse files
committed
fix re-schedule bug for missed intervals
1 parent 475ee0e commit 6f67e52

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

schedule.go

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ func NewSchedule(redisClient *redis.Client) Schedule {
3535
func (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

Comments
 (0)