Problem/Motivation

When using the Trash module,
deleted entities are stamped with a timestamp in the deleted column
of their data table. The getQuery() method in LinkExtractorBatch
does not filter out these entities, so they are returned as candidates for extraction.
However, loadMultiple() does not return soft-deleted entities, causing a
mismatch between the IDs found by the query and the entities actually loaded.

This results in an infinite loop during drush linkchecker:analyze or
the UI batch process, where the same unloadable entity IDs are returned on every batch
run but never processed, preventing the batch from ever finishing.

The same infinite loop can also occur with other types of database inconsistencies
where an entity exists in the index tables but cannot be loaded by
loadMultiple().

Steps to reproduce

  1. Install the Trash module.
  2. Delete one or more nodes (move them to trash).
  3. Run drush linkchecker:analyze.
  4. The process gets stuck and never reaches 100%.

Proposed resolution

Fixes in LinkExtractorBatch:

  1. Filter deleted entities in getQuery(): Check
    if the entity's data table has a deleted column (indicating the Trash
    module or similar is installed) and add an IS NULL condition to exclude
    deleted entities from extraction candidates.
  2. Handle unloadable entities: If loadMultiple()
    returns fewer entities than IDs were found, mark the missing IDs as indexed in
    linkchecker_index and log a warning. This prevents an infinite loop
    for any type of DB inconsistency and gives administrators visibility into the problem.
  3. Add infinite loop guard to batchProcessEntities():
    If processEntities() returns 0 processed items, mark the batch as
    finished regardless of the total count. This is a safety net to prevent infinite
    loops from any future edge case.

Remaining tasks

  • Review and testing
Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

andrerb created an issue. See original summary.

shank115’s picture

Status: Active » Needs review
andrerb’s picture

Assigned: andrerb » Unassigned

codebymikey made their first commit to this issue’s fork.

codebymikey’s picture

codebymikey’s picture

Attached static patch without composer.json, info.yml and cspell changes since the info.yml leads to conflicts when applied on composer.