Problem/Motivation
Situation where documents are left in near perpetual state of not being processed by elasticsearch_helper.
We are processing up to 1 million entities per day and somehow we have some entities remain un-indexed or almost never re-indexed for several days or longer.
Queues in relation to data processing should be based on the First In, First Out-principle (FIFO). Somehow this module has cluttered this 🤷‍♂️ If the queue fetch orders by created, then changing created on already-queued items will break FIFO and can potentiale starve "hot" entities that get updated frequently.
Look at the queue item_id and created values for these two queue items:
155906822 - 1757493556
156680940 - 1757443410
Last item (156680940) was queued 700.000 items after the first one, but still has a lower created timestamp and thus will be processed before the actual first item (155906822)
Steps to reproduce
Have a large set of entities which are continusly being updated and/or added.
The result is that exisiting items which are continusly updated on a daily basis have a chance to remain in queue for unexpectedly long time.
Cause of problem:
- The created timestamp is updated
- Query for fetching items sorts on created timestamp
Since the item_id remains the same, the created timestamp value should remain the same(!) There is an assumption to be made that when the primary key value is created, the created timestamp is related to that specific value. Take a look at Drupal entities tables in general. There is a reason why there is a created field and an changed field - one should not change the created value - that voids the reason for having a created value.
Proposed resolution
Remove sort by created value in this query.
https://git.drupalcode.org/project/drupal/-/blob/11.x/core/lib/Drupal/Co...
Or remove the update of created timestamp. Or do both. Queues should be FIFO and elasticsearch_helper breaks that with this doCreateItem function:
protected function doCreateItem($data) {
// Serialize the data.
$serialized = serialize($data);
$query = $this->connection
->merge(static::TABLE_NAME)
->keys([
'name' => $this->name,
'entity_type' => $data['entity_type'],
'entity_id' => $data['entity_id'],
])
->fields([
'name' => $this->name,
'data' => $serialized,
'created' => time(),
'entity_type' => $data['entity_type'],
'entity_id' => $data['entity_id'],
]);
return $query->execute();
}
Comments
Comment #2
erlendstromsvik commentedComment #3
erlendstromsvik commentedComment #4
erlendstromsvik commented