mirror of
https://github.com/hibiken/asynq.git
synced 2026-04-25 23:15:51 +03:00
[GH-ISSUE #265] [FEATURE REQUEST] Processed job's payload and result #1116
Labels
No labels
CLI
bug
designing
documentation
duplicate
enhancement
good first issue
good first issue
help wanted
idea
invalid
investigate
needs-more-info
performance
pr-welcome
pull-request
question
wontfix
work in progress
work in progress
work-around-available
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/asynq#1116
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Originally created by @unicod3 on GitHub (Apr 24, 2021).
Original GitHub issue: https://github.com/hibiken/asynq/issues/265
Originally assigned to: @hibiken on GitHub.
Is your feature request related to a problem? Please describe.
Asynq currently removes the successfully processed jobs from Redis.
That means the information about the processed jobs also vanishes like;
Describe the solution you'd like
It would be nice to keep processed jobs until a given TTL and return a basic struct that contains something like
id, queued_at, completed_at.I think to achieve that, the first thing is to generate a unique id for each task and keep them like
asynq:{default}:processed:{job_id}Describe alternatives you've considered
Python RQ or Laravel Horizon might be good examples to take a look at.
@hibiken commented on GitHub (Apr 24, 2021):
@unicod3 Thank you for opening this issue!
Yes, I have been thinking about a feature like the one you described. I really like assigning TTL duration for completed task to keep them around. We can expose that option as a new
Optiontype.Example:
In addition to those timestamps you mentioned, it'd be nice (in some scenarios) to allow users to store "result" associated with the task. (We need to be careful what we store in redis, however, since it may use up too much memory).
Currently I'm thinking about exposing a type called
ResultWriterthrough context to write task's result.Example:
I'm in the process of re-designing the redis key so that each task gets its own key in redis and values are stored as HASH so it'd be quite easy to implement something like this.
I'll update this thread when I have a concrete plan to go forward with this feature 👍
@unicod3 commented on GitHub (Apr 24, 2021):
That sounds nice, if you could create something like a milestone or tasks, I also would love to participate in implementing.
@hibiken commented on GitHub (Sep 9, 2021):
I'm revisiting this thread together with #322.
My current (tentative) plan is to make the following changes:
ResultTTL(time.Duration) Optionhelper to specify TTL after success processingasynq:{qname}:completedZSET score being the timestamp of TTL expiryResultWritertype that writes result for the given task andGetResultWriter(ctx) ResultWriterhelper to get the writer"result"field under task keyasynq:{qname}:t:{task_id}Also I'm considering changing the
NewTaskfunction to take Options as variadic argumentsExample:
@hibiken commented on GitHub (Nov 6, 2021):
This feature is now available since version 0.19
@tpoxa commented on GitHub (Nov 20, 2021):
Thanks, @hibiken Would be great to have an example of the usage.
@tpoxa commented on GitHub (Nov 20, 2021):
I keep receiving an empty result within my taskInfo
@hibiken commented on GitHub (Nov 21, 2021):
@tpoxa Thank you for the comment! I'll make sure to add some examples in the godoc and wiki #354
But in the meantime, this is a simple example.
Then you should be able to see the result payload in the Web UI or read that result bytes programmatically by calling
Inspector.GetTaskInfo. Let me know if you have further questions. Also make sure that you are using asynq v0.19 👍@tpoxa commented on GitHub (Nov 21, 2021):
Sorry, does not work.
github.com/hibiken/asynq@9f2c321e98/client.go (L379)is that ok that Result returned is always nil?@hibiken commented on GitHub (Nov 21, 2021):
I think there's some misunderstanding here.
TaskInforeturned fromClient.Enqueuewill always have nil result because you just enqueued the task and haven't handled them in your Handler.Result will be available after you write result in your handler. Just make sure you set the
Retentionoption so that the tasks don't get deleted once they are processed successfully.@tpoxa commented on GitHub (Nov 21, 2021):
Yes, it might be a misunderstanding.
Yes, I did set up retention time, so how I can get the actual result?
I thought I enqueue tasks synchronously so I must have a result in task info.
How does the enqueuer know that a task is accomplished?
Thank you!
Sorry for the silly questions.
@hibiken commented on GitHub (Nov 21, 2021):
Enqueueonly puts the given task on a queue to be handled asynchronously by workers (Are you running the worker server process with yourHandler?), only after the Handler processes the task the result will be available (Assuming that you write result using theResultWriter, see example above).Unfortunately there's no out-of-the-box solution to listen on the event when the task is completed. You just need to query the task using
Inspector.GetTaskInfoif you want to do this programatically.If you don't mind, could you describe your use case? The main motivation behind implementing this feature was to prepare for #244 feature which we'll implement in the future.
@tpoxa commented on GitHub (Nov 21, 2021):
Ok, for example. Webform sends a task, get a website's screenshot. The user submits the URL and waits for a few seconds (up to 30) when it's done. As the result, the website shows a screenshot URL.
One of the workers gets a payload (website URL) makes a screenshot, publishes it to the bucket, and returns URL of the uploaded image.
@tpoxa commented on GitHub (Nov 21, 2021):
So ideal (IMHO) it would be to have something like this:
@crossworth commented on GitHub (Nov 21, 2021):
Hello, I don't think this would work. I mean the
waitwould have to useInspector.GetTaskInfoin a loop with a timer to know when the task is finished, but if this is the case, I think using a goroutines and channels would be better, or if you really need to wait maybe doing it synchronously without a goroutine should work as well.Maybe you should generate a task with an ID and create a route that uses
Inspector.GetTaskInfoand check it periodically on the frontend?Since you are taking websites screenshot's you could use the URL as key.
Route that enqueues the job
screenshot:https//google.com.br(you could add timeout and unique options as well, this way if two requests are made for the same URL would generate the same key and you would only need to process they one time)screenshot:https//google.com.brRoute that check the job result
Inspector.GetTaskInfoto check the task resultYour frontend could use javascript to query the route that checks the job result every 5seconds.
@tpoxa commented on GitHub (Nov 21, 2021):
Ok, guys thanks. I came up with sth like this:
Where wait function is next: