claimItem()'s docs say:
* On success we return an item object. If the queue is unable to claim an
* item it returns false. This implies a best effort to retrieve an item
* and either the queue is empty or there is some other non-recoverable
* problem.
However, it's possible to return NULL here:
while (TRUE) {
try {
$item = $this->connection->queryRange('SELECT data, created, item_id FROM {' . static::TABLE_NAME . '} q WHERE expire = 0 AND name = :name ORDER BY created, item_id ASC', 0, 1, [':name' => $this->name])->fetchObject();
}
catch (\Exception $e) {
$this->catchException($e);
// If the table does not exist there are no items currently available to
// claim.
return FALSE;
}
if ($item) {
*** get an item ***
// Try to update the item. Only one thread can succeed in UPDATEing the
// same row. We cannot rely on REQUEST_TIME because items might be
// claimed by a single consumer which runs longer than 1 second. If we
// continue to use REQUEST_TIME instead of the current time(), we steal
// time from the lease, and will tend to reset items before the lease
// should really expire.
$update = $this->connection->update(static::TABLE_NAME)
->fields([
'expire' => time() + $lease_time,
])
->condition('item_id', $item->item_id)
->condition('expire', 0);
// If there are affected rows, this update succeeded.
if ($update->execute()) {
$item->data = unserialize($item->data);
return $item;
}
*** fail to run the update query ***
}
else {
// No items currently available to claim.
return FALSE;
}
*** fall out of the if() block and end up here ***
*** end of method returns NULL ***
}
Therefore, there should be an else for the if ($update->execute()) block that returns FALSE.
Comments
Comment #2
vadim.hirbu commentedAdd return FALSE when update query is failing.
Comment #3
vadim.hirbu commentedComment #4
vadim.hirbu commentedComment #5
joachim commentedThanks for the patch! Looks good.
Comment #6
alexpottEr... I'm not sure this is right. We're in a
while (TRUE) {loop so ifif ($update->execute()) {is not successful I think we're going to loop around again.I think this is closed works as designed.
Comment #7
joachim commentedYes, I think you're right.
I wonder if we should refactor this method to make it easier to see this is what's going on?
Maybe instead of:
have a guard clause that goes:
Comment #8
alexpottSure we can do that. Maybe something like
Is easier to grok... less returns in a loop do make things simpler.
Comment #9
vadim.hirbu commentedUpdated code according latest mentions and tested on latest version of drupal (8.8.x). All works as expected. Added patch.
Comment #10
alexpottcan now become
For one less return.
Comment #11
vadim.hirbu commentedComment #12
johnhelmuthComment #13
johnhelmuthReviewed code, seems OK to me with the changes last requested. Patch applied cleanly. Site seems to work when running with this patch applied.
Comment #14
johnhelmuthReviewed code and it looks OK to me, and includes the last changes requested.
Patch applied cleanly. Ran queue related tests on simplytest.me and they passed.
Comment #16
yogeshmpawarAll looks good so setting back to Needs Review! Tests failure is not related (see #3055648: Frequent random fail in \Drupal\Tests\media_library\FunctionalJavascript\MediaLibraryTest).
Comment #17
subhojit777Comment #18
borisson_This does make it a lot more readable, I'm a big fan of this change. Great work!
Comment #20
catchCommitted e5fc916 and pushed to 8.8.x. Thanks!