Like others I often get the message to run update manually because updates weren't successfully checked by cron..

When I do it takes forever and appears to be checking the modules multiple times.. For 47 enabled modules its checked 795 projects.. If everyone is having this the update servers must be getting hammered..

When running it a second time it runs through quickly..

It seems that when a check fails on a cron run it keeps the queue that it needs to check so if the cron checking has failed multiple times then the queue becomes huge and causes the multiple checks..

Wouldn't it be better to cleat the existing queue when an update check is initiated?

Comments

pfrenssen’s picture

Status: Active » Closed (duplicate)
jonhattan’s picture

Version: 7.10 » 7.x-dev
Priority: Normal » Major
Status: Closed (duplicate) » Active

I've seen this via web. Doesn't seen a drush issue.

mysql> select count(*) from queue where name="update_fetch_tasks";
+----------+
| count(*) |
+----------+
|      963 |
+----------+
1 row in set (0.00 sec)
berdir’s picture

Yeah, there's something seriously going wrong with update.module. I've seen multiple sites which ended up with *thousands* of entries in the queue.

rooby’s picture

Yeah, with drush I regularly have it checking all the installed modules multiple times and I have at least once seen the drupal available updates report check > 2000 modules.

catch’s picture

This might be why so many people are reporting #1484216: Race condition in _update_create_fetch_task() (PDO Exceptions) too.

pfrenssen’s picture

I'm investigating this. I noticed there is a time limit set on the function that cleans out the queue before starting the update process. This is set to 5 seconds by default. Maybe this is causing it, and if it does then perhaps the update process should be aborted if the queue could not be cleaned out in time.

Edit: I'm wrong about this.

catch’s picture


function _update_create_fetch_task($project) {
  $fetch_tasks = &drupal_static(__FUNCTION__, array());
  if (empty($fetch_tasks)) {
    $fetch_tasks = _update_get_cache_multiple('fetch_task');
  }
  $cid = 'fetch_task::' . $project['name'];
  if (empty($fetch_tasks[$cid])) {
    $queue = queue('update_fetch_tasks');
    $queue->createItem($project);
    db_insert('cache_update')
      ->fields(array(
        'cid' => $cid,
        'created' => REQUEST_TIME,
      ))
      ->execute();
    $fetch_tasks[$cid] = REQUEST_TIME;
  }
}

OK so there's a race condition here - before the update_fetch_task item is created, any number of processes could be creating queue items simultaneously. Probably the easiest change would be to add a lock, which in turn would fix #1484216: Race condition in _update_create_fetch_task() (PDO Exceptions).

catch’s picture

Status: Active » Closed (duplicate)
pfrenssen’s picture

Status: Closed (duplicate) » Active

New update tasks are added to the queue in _update_create_fetch_task(). This function checks if this update is queued by looking in the {cache_update} table, not if it actually exists in the queue. So if there is a discrepancy between {cache_update} and the queue, it will happily pile up tasks to the queue.

_update_cache_clear() will clear out items from the {cache_update} table, without removing them from the queue. I think this is how the discrepancies occur.

I'm not sure how this should be solved.

  1. We could avoid adding tasks to the queue that already exist in the queue. I don't see a way however to do this, because the Queue API does not support querying for existing tasks.
  2. We could loop through the queue and purge all update tasks when the update cache is cleared. I would not like to add this to _update_cache_clear() though because of Code Smell®.
pfrenssen’s picture

Status: Active » Closed (duplicate)

Sorry cross posted.

pfrenssen’s picture

Issue summary: View changes

Hit save to quickly..