-
Notifications
You must be signed in to change notification settings - Fork 106
Description
I had left this comment in #106, but figured it was worth asking more directly...
I find it very strange that named tasks will always Exists once added to a queue when it seems like they should stop existing once successfully executed... but Storage only has a single Exists method, which means Consumer has no way to remove a successfully executed task from storage.
RedisStorage holds these for 24hr and LocalStorage will hold them until 128,000 additional tasks have been queued.
An example:
- Create a task and give it a name like
spider_www_google_com - Attempt to add a second task with the name
spider_www_google_com- taskq rightfully returnstaskq.ErrDuplicate spider_www_google_comtask completes successfully and isconsumer.Putis called which callsconsumer.delete, which callsQueue.Delete... this callsRedis.XDelon the ID for Redis andscheduler.Removefor memqueue- Attempt to add a new task with the name
spider_www_google_com- taskq returnstaskq.ErrDuplicate
I would expect step 4 to succeed, but it fails because RedisStorage.Exists calls SetNX on the task's name whereas the call to XDel is on the task's ID ... which leaves the name lock lingering for 24hr. Similarly, LocalStorage.Exists puts the name in a LRU cache (of size 128,000) whereas scheduler.Remove is a map based with the task's pointer as its key.
The easy fix is to extend the Storage interface to have a Delete method that can be called when a task is completed successfully... however, for Redis it is probably best to simply pass both the task's ID and name to XDel to avoid needing a second round-trip to Redis and then leaving RedisStorage.Delete to do nothing.
Thoughts? Am I missing something here?