[GH-ISSUE #864] [FEATURE REQUEST] Add callback for task state changes #426

Open
opened 2026-03-02 05:21:07 +03:00 by kerem · 2 comments
Owner

Originally created by @hungtcs on GitHub (Apr 17, 2024).
Original GitHub issue: https://github.com/hibiken/asynq/issues/864

Originally assigned to: @hibiken on GitHub.

Is your feature request related to a problem? Please describe.

I'm currently working on a feature that notifies other services when a task has finished.
Unfortunately, I found that asynq doesn't provide an api for this feature.

I currently do this via middleware, but it has some flaws and doesn't work well.

One of the key issues is that the life cycle of the task does not actually end when the middleware is executed.
If another service is notified of the end of the task at this point, however, it may still be active when the other service gets the task status from the inspector.

func TaskFinishEventMiddleware() asynq.MiddlewareFunc {
	return func(h asynq.Handler) asynq.Handler {
		return asynq.HandlerFunc(func(ctx context.Context, t *asynq.Task) error {
			var taskId string
			var queueName string
			if val, ok := asynq.GetQueueName(ctx); ok {
				queueName = val
			} else {
				return fmt.Errorf("can not get queue name from task context")
			}
			if val, ok := asynq.GetTaskID(ctx); ok {
				taskId = val
			} else {
				return fmt.Errorf("can not get task id from task context")
			}

			var taskErr = h.ProcessTask(ctx, t)

			// Send notifications to other services to notify the end of the task
						
			return taskErr
		})
	}
}

Describe the solution you'd like

One solution is to add a global callback function that is called when the task state changes.

var server = asynq.NewServer(redisClientOpt, asynq.Config{
	Queues:   queues,
	Logger:   log.Log,
	LogLevel: logLevel,

	// Add new callback 
	TaskStateChange: func(taskInfo *asynq.TaskInfo) {

	},
})

Describe alternatives you've considered

I'm currently using middleware, but it's not working well.

Originally created by @hungtcs on GitHub (Apr 17, 2024). Original GitHub issue: https://github.com/hibiken/asynq/issues/864 Originally assigned to: @hibiken on GitHub. **Is your feature request related to a problem? Please describe.** I'm currently working on a feature that notifies other services when a task has finished. Unfortunately, I found that asynq doesn't provide an api for this feature. I currently do this via [middleware](https://github.com/hibiken/asynq/wiki/Handler-Deep-Dive#using-middleware), but it has some flaws and doesn't work well. One of the key issues is that the life cycle of the task does not actually end when the middleware is executed. If another service is notified of the end of the task at this point, however, it may still be active when the other service gets the task status from the inspector. ```go func TaskFinishEventMiddleware() asynq.MiddlewareFunc { return func(h asynq.Handler) asynq.Handler { return asynq.HandlerFunc(func(ctx context.Context, t *asynq.Task) error { var taskId string var queueName string if val, ok := asynq.GetQueueName(ctx); ok { queueName = val } else { return fmt.Errorf("can not get queue name from task context") } if val, ok := asynq.GetTaskID(ctx); ok { taskId = val } else { return fmt.Errorf("can not get task id from task context") } var taskErr = h.ProcessTask(ctx, t) // Send notifications to other services to notify the end of the task return taskErr }) } } ``` **Describe the solution you'd like** One solution is to add a global callback function that is called when the task state changes. ```go var server = asynq.NewServer(redisClientOpt, asynq.Config{ Queues: queues, Logger: log.Log, LogLevel: logLevel, // Add new callback TaskStateChange: func(taskInfo *asynq.TaskInfo) { }, }) ``` **Describe alternatives you've considered** I'm currently using middleware, but it's not working well.
Author
Owner

@hibare commented on GitHub (Jul 17, 2024):

Looking for same feature, probably experiment with middleware for now. Having a concrete solution would be awesome.

<!-- gh-comment-id:2233854830 --> @hibare commented on GitHub (Jul 17, 2024): Looking for same feature, probably experiment with middleware for now. Having a concrete solution would be awesome.
Author
Owner

@kamikazechaser commented on GitHub (Oct 19, 2024):

I think the middleware should suffice, taskErr will report if it is a retry, if there is no error, you can use the inpsector to grab the latest state.

<!-- gh-comment-id:2423715885 --> @kamikazechaser commented on GitHub (Oct 19, 2024): I think the middleware should suffice, taskErr will report if it is a retry, if there is no error, you can use the inpsector to grab the latest state.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/asynq#426
No description provided.