mirror of
https://github.com/hibiken/asynq.git
synced 2026-04-26 07:25:56 +03:00
[GH-ISSUE #322] [FEATURE REQUEST] Support for ULID in TaskMessage ID field #2162
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#2162
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 @dhh93 on GitHub (Sep 5, 2021).
Original GitHub issue: https://github.com/hibiken/asynq/issues/322
Originally assigned to: @hibiken on GitHub.
Hey there,
Was wondering if we could add support for ULID in the
TaskMessageID field. The first 10 characters of each ULID string encode timestamp information, which would enable the sorting of tasks by ID.There is another library (albeit 3rd party) that implements ULIDs with a similar API to the UUID library, though it would require a little work to to make the two interchangeable within asynq.
uuid.New, which takes no arguments, whileulid.Newneeds auint64timestamp and anio.Readeras an entropy source.time.Now()andrand.Reader(ornil) seem like sensible defaults.uuid.MustParse. which returns aUUIDtype whileulid.MustParsereturns aULIDtype.Given the two differences above, it looks like a custom type would have to be implemented to support both, but it shouldn't be too much of a hassle.
Happy to submit a PR to help implement if needed.
Cheers.
@hibiken commented on GitHub (Sep 7, 2021):
@dhh93 Thank you for creating this issue!
To better understand the motivation behind the change; why do you need to sort tasks by the timestamp?
I'm guessing the timestamp is the time the task was enqueued or created?
@ryan961 commented on GitHub (Sep 8, 2021):
@hibiken hi😊,I have a similar need. First, I really liked the project and put it into production, although it's still in beta.I use it as a cache synchronization queue. I update the data in Redis and equeue the update operation to the asynq queue (schedule queue). The asynq server pulls tasks off queues and synchronize update operations to the database. To reduce database stress, I pass
asynq.ProcessIn(300*time.Second)options to tune task processing behavior at enqueue time,if the same operation happening in the 5 minutes,I will re-equeue this update operation task and also pass
asynq.ProcessIn(300*time.Second)options . So I need to set the same task ID to override the last task. I addtaskIdOption.@hibiken commented on GitHub (Sep 8, 2021):
@Ryalu you should probably achieve similar effect by passing
Unique(ttl)option when enqueueing the task.Example:
@ryan961 commented on GitHub (Sep 8, 2021):
Thank you for replying.
It can ensure that tasks are not executed repeatedly, but can't override the same task. such as:
I create a task to update item (
UPDATEitemsSETnumber=500 WHERE customerId = 3 AND item = 2) and enqueueclient.Enqueue(task, asynq.TaskId("customerId:3:item:2"), asynq.ProcessIn(300*time.Second)). After the 30 seconds, I need to re-enqueue task("customerId:3:item:2")(UPDATEitemsSETnumber=1000 WHERE customerId = 3 AND item = 2) again. I also enqueueclient.Enqueue(task, asynq.TaskId("customerId:3:item:2"), asynq.ProcessIn(300*time.Second)). For mysql, it only executeUPDATEitemsSETnumber=1000 WHERE customerId = 3 AND item = 2.@hibiken commented on GitHub (Sep 8, 2021):
Ok thank you for clarifying!
To address the initial feature request by @dhh93 and follow up request by @Ryalu, I think we can provide
TaskID(string)option when enqueueing tasks to allow users to provide a custom task ID.@Ryalu I think
Client.Enqueueshould returnErrDuplicateTaskif task with the given ID already exists. I think we can add a method toInspectorto update an existing task with the given ID.Example:
So my proposed changes are the following:
func TaskID(custom_id string) Optionto allow custom task IDs(i *Inspector) UpdateTask(id string, payload []byte) (*TaskInfo, error)to allow updating existing task@dhh93 @Ryalu Let me know if you have any feedback/thoughts!
@dhh93 commented on GitHub (Sep 8, 2021):
Appreciate the response, @hibiken. With regards to your initial question, I wanted to incorporate ULIDs to help with logging/tracing; I think this somewhat ties in to Issue #321 as well. Having sortable, unique IDs really helps with parsing through aggregated logs/requests across an entire system.
The proposed changes look good -- allowing for custom IDs in general is nice since users can work with the
InspectorAPI to manage tasks without keeping a separate mapping of theasynqspecific Task ID & their own systems'.I think the library should stick with
UUIDas the default to minimize disruption to those who rely on it. Having the functional option that you suggested is probably the best way to implement custom user IDs, though theDecodeMessagefunction may have to be changed to accommodate a string instead of unmarshaling to aUUIDlike it is currently doing now.github.com/hibiken/asynq@05534c6f24/internal/base/base.go (L264)@crossworth commented on GitHub (Sep 24, 2021):
@hibiken this can be closed I guess.
Seems that the PR failed to close this issue when was merged.
@hibiken commented on GitHub (Sep 30, 2021):
@crossworth The change is not in master yet. The branch was merged into
nextbranch which I will merge once I'm ready to release a new version :)@hibiken commented on GitHub (Nov 6, 2021):
This has landed in master now and available since version 0.19