The scenario is a bit complicated and does (I think) require custom code, but I’d say this should still work well in the Search API – and currently doesn’t. Steps to reproduce:
- Create an index with “Index items immediately” enabled.
- Use a custom datasource that ignores some items/entities based on their properties. E.g., this could be a datasource that only tracks published items.
- Perform some action that, in a single page request, will track an item first as updated, and then as deleted, by the datasource.
- (For testing purposes, you can also replace the previous two steps by manually calling first
Index::trackItemsUpdated()and thenIndex::trackItemsDeleted()on the same item(s).) - The expected result here would, of course, be that the item is missing from both the tracking table and the server.
- Actually, however, it will only be missing from the tracking table, but still be on the server. The reason for this is that the delete from the server happens immediately when tracking it, while the indexing operation is only queued when the update is tracked and happens via
PostRequestIndexing, at the end of the page request. Therefore, the update “overwrites” the delete.
As said, the setup is quite complicated, and probably rare, but I still think this qualifies as a bug in the Search API: when you track the deletion of an item, you wouldn’t expect it to be indexed afterwards.
As a side note, the reason this cannot happen with our own Content Entity datasource (as far as I can see) is that this only discards items based on their type or language. Since the type is immutable and the language is part of the ID (and not really a regular property at all, I’d say), the scenario described here cannot happen. (Except when changing the datasource settings and updating an item twice, all in the same page request.)
| Comment | File | Size | Author |
|---|---|---|---|
| #3 | 3325206--2-do_not_index_deleted_items--tests_only.patch | 1.88 KB | drunken monkey |
| #2 | 3325206--2-do_not_index_deleted_items.patch | 3.96 KB | drunken monkey |
Comments
Comment #2
drunken monkeyThis should fix the problem: when tracking the deletion of an item, also remove it from the
PostRequestIndexingqueue.Comment #3
drunken monkeyComment #5
drunken monkeyComment #6
andriy khomych commentedHey Thomas. I've tested this patch locally and it fixed the issue for my test case.
Moving it to RTBC.
Comment #8
drunken monkeyGood to hear, thanks a lot for testing.
Merged. Thanks again!
Comment #9
andriy khomych commentedThank you, Thomas!
Comment #11
andriy khomych commentedHey Thomas :)
I've now faced another issue when we have multiple tracking/untracking/tracking/untracking/tracking/untracking in the same request
it can end up with a tracking entity that should be untracked and stored with tracked status (which is incorrect).
What about queueing tracking calls and executing the latest one after the actual request finishes? E.g. by using https://api.drupal.org/api/drupal/includes%21bootstrap.inc/function/drup...