#1484216: Race condition in _update_create_fetch_task() (PDO Exceptions) exposed some one-off code in update module that attempts to keep queue items unique. Maintaining a queue alongside a separate key/value store, itself based on a forked version of the cache system, is not ideal.
Seems like having queue class for unique items could be useful generally, and would definitely simplify that part of update module.
Comment | File | Size | Author |
---|---|---|---|
#19 | really_D7_this_time.patch | 2.52 KB | catch |
#17 | update_fetch_tasks_D7.patch | 2.51 KB | catch |
#10 | do_not_delete_fetch_tasks-with-tests.patch | 2.55 KB | Berdir |
#10 | do_not_delete_fetch_tasks-only-tests.patch | 1.44 KB | Berdir |
#9 | do_not_delete_fetch_tasks.patch | 1.11 KB | Berdir |
Comments
Comment #1
chx CreditAttribution: chx commentedredis_ssi module bends over backwards to implement this. Huge, huge +1
Ps. You are welcome to borrow the code from there ;)
Comment #2
MrMaksimize CreditAttribution: MrMaksimize commentedWe've been working on a module for some of our own needs in Drupal 7 centered around synchronizing feeds and REST calls. I think this is a good start to a unique queue system http://drupal.org/sandbox/MrMaksimize/1399810 and with some molding could be adapted to core.
At the moment, the module adds two tables to the queue table - q_key and q_item_id. Since it's feeds adapted, we're using q_key to store feed_nid, and q_item_id to store the serial id of the data we're importing (user, node, etc). At the moment it's pretty much adapted only for systemQueue, I haven't even tried with the memoryQueue
My coworkers pointed me to this issue and we'd love to help out with getting this into core!
Comment #3
catchSince this is the 'proper' fix for #1484216: Race condition in _update_create_fetch_task() (PDO Exceptions) I'm going to bump it to major.
Comment #4
Anonymous (not verified) CreditAttribution: Anonymous commentedi don't like the idea of a 'unique queue'. i'd prefer we keep the 'unique' tracking out of the queue and in a tracking table.
that's sort of what the code does now, only really badly. if we stop treating that like a cache table, and run the update task creation through a single function that checks for existing queue entries via a tracking table, we're done.
if we put this idea in the queue, we can no longer swap it out. how, for example, do you implement a 'unique queue' with beanstalkd?
Comment #5
BerdirAs per discussion in IRC, this could be a separate API.
In fact, isn't it very similar to locking, just without timeout?
Comment #6
Anonymous (not verified) CreditAttribution: Anonymous commentedcompletely untested code:
then _update_create_fetch_task becomes:
UPDATE: fix stupid typo with unique item function call.
Comment #7
Anonymous (not verified) CreditAttribution: Anonymous commentedless derp-filled version, so it's possible to know how old a queue item is:
Comment #8
BerdirOne issue with this is that the module that is using this function needs to additionally place $key somehow in in $data itself, so that it can then call drupal_unique_queue_item_delete($key). Or know how to regenerate the key based on $data.
Wondering if it would make sense to use the name of the queue as well in key(), that would help to prevent conflicts between different queues and possibly allow to clear a queue if need be. Does make it even harder to do the delete as you need to load the queue again there, which means that you can't have a worker callback that can handle multiple queues or you need to add that information into $data as well :(
Comment #9
BerdirI've been thinking about this a bit.
Backporting this to Drupal 7 might not be easy.
However, from what I can see, fixing the actual bug in update.module is absolutely trivial.
All we need to do is ensure that calls to _update_cache_clear() without argument do not clear the fetch task thingies. That's almost a one line change, see attached patch. Because update.module already makes sure that it clears the specific fetch task when he is processed. Additionally, it is possible that calls without a specific cid should actually only delete a bunch of specific cid's.. for example, there is no need to delete fetch data for 200 projects if you enable a theme. In fact, doing that is madness ;) (And no, it's not sparta either).
Not sure if we want to do this here, in the existing issue or create a new one. I think either the other one or a new task and then this one is not a major task but a normal and maybe even a feature request that does not need to be backported.
Comment #10
BerdirOk, attached are tests for this bug, with and without the fix.
Comment #12
BerdirUh, since when does the testbot set an issue to needs work if one of the patches does not pass tests?
Comment #13
catch@berdir, depends on the order of the patch files. Also more or less forever:)
Comment #14
catch#10 looks good to me, it'd be good to abstract this out, but let's get the duplicate items issue fixed.
Comment #15
BerdirChanging component.
Comment #16
Anonymous (not verified) CreditAttribution: Anonymous commentedjust a me too, this is the simplest possible fix, and is ready to fly IMO.
Comment #17
catchCommitted/pushed to 8.x. Patch applies cleanly to 7.x with p2, so attaching that and leaving at RTBC for 7.x.
Comment #19
catchqueue() vs. DrupalQueue::get() in the test.
Comment #20
Anonymous (not verified) CreditAttribution: Anonymous commentednice fix catch, this is ready to go.
Comment #21
BerdirOpened a new issue for the original purpose of this one. #1548286: API for handling unique queue items
Comment #22
webchickCommitted and pushed to 7.x. Thanks!
Comment #24
catchComment #25
jonhattanRemoving tag
Comment #27
dwwNever got backported to D6, but seems more appropriate to call this "fixed"...