hibiken / asynq

Simple, reliable, and efficient distributed task queue in Go
MIT License
9k stars 659 forks source link

Scheduler: How to get the schedule time of the task in the task handler? #890

Closed asravankumar closed 1 week ago

asravankumar commented 1 month ago

I have a requirement, where i require the scheduled time of a task in the handler. For example, I have a task A which is scheduled to invoke every day, then in the task handler I need the scheduled time to tag the task invocation to that day.

For the same, I did the following. I passed the scheduledAt as part of the payload. While registering the task in the scheduler, I gave the time.Now().UTC() to get the current time.

type sampleTaskPayload struct {
    UserID      int       `json:"user_id"`
    ScheduledAt time.Time `json:"timestamp"`
}

func SampleTask(id int, scheduledAt time.Time) (*asynq.Task, error) {
    fmt.Println("task", TypeSample)
    payload, err := json.Marshal(sampleTaskPayload{UserID: id, ScheduledAt: scheduledAt})
    if err != nil {
        return nil, err
    }
    return asynq.NewTask(TypeSample, payload), nil
}

scheduler := asynq.NewScheduler(
        asynq.RedisClientOpt{Addr: app_config.Cfg.ASYNQ_REDIS_URL},
        &asynq.SchedulerOpts{
            Location: loc,
        },
    )

    createTask := func() *asynq.Task {
        currentTime := time.Now().UTC()
        task, _ := task.SampleTask(1, currentTime)
        return task
    }

    //sampleTask, _ := task.SampleTask(1, time.Now().UTC())
    scheduler.Register(
        "*/1 * * * *",
        func() (*asynq.Task, error) {
            return createTask(), nil
        },
        asynq.Unique(1*time.Hour),
        asynq.Queue("queue"),
    )

You can see above while registering, I created the task with current time. What i see is for the all the invocations of this task, the scheduledAt value is constant and is basically the time at which that code has been executed.

I think my approach might be wrong.. Please help me in two things,

RiskyFeryansyahP commented 4 weeks ago

Hi @asravankumar, you can use Periodic Task Dynamic with the GetConfigs implementation that will be fetched at every interval (configurable). For the payload, you can use a map, DB, or something else to keep the data dynamic. Every time a task is executed, you need to update the data in the map, DB, or other storage solution.