Performance issue when there are many links

Created on 11 June 2025, 25 days ago

Problem/Motivation

There is a performance issue when editing multilingual nodes with a large number of links (approximately 100 or more). The editing process becomes excessively slow due to the time it takes to analyze the links, often resulting in a timeout.

Enabling the option “Recalculate dependencies using queue” mitigates the problem by deferring the analysis to the queue system. However, when this option is used, the Entity Mesh table is not updated immediately, but only after the queue is processed (typically during cron execution). This creates a discrepancy between the node's saved state and its visual representation in the Entity Mesh table.

Steps to reproduce

  • Create or edit a multilingual node with a large number of linked entities (e.g., 100+).
  • Ensure that the “Recalculate dependencies using queue” option is disabled.
  • Save the node.
  • Observe that the process is slow and may result in a timeout.
  • Enable the “Recalculate dependencies using queue” option.
  • Save the same node again.
  • Note that the Entity Mesh table is not updated until the next cron execution.

Proposed resolution

Three possible solutions are proposed:

  • Enable “Recalculate dependencies using queue” by default to avoid performance bottlenecks.
  • Detect high link count and defer processing automatically: If the option is disabled and the system detects a large number of links, automatically queue the dependency recalculation. Notify the user that the Entity Mesh table will not update until the queue is processed.
  • Introduce a batch processing button on the node edit form or confirmation page to allow manual execution of the dependency recalculation process via a batch API operation.

Remaining tasks

  1. Evaluate and decide on the preferred solution(s).
  2. Update module configuration defaults if necessary.
  3. Implement logic to detect high link counts and defer processing.
  4. Create user notifications or messages informing of delayed Entity Mesh updates.
  5. Add a batch processing button with appropriate permissions and UX design.
  6. Write automated tests covering each scenario.
  7. Update documentation.

User interface changes

Optional: A message shown to the user when dependency analysis is deferred due to high link volume.

Optional: A button to manually trigger batch processing of dependency recalculations.

API changes

None expected, unless a new service or batch handler is introduced for dependency recalculation.

Data model changes

None.

🐛 Bug report
Status

Active

Version

1.0

Component

Code

Created by

🇪🇸Spain lpeidro Madrid

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @lpeidro
  • 🇪🇸Spain lpeidro Madrid

    Final Solution:

    A radio button will be provided with two options: Synchronous and Asynchronous.

    Each option will include a description explaining its functionality. Please note that the asynchronous option relies on queues and cron jobs.

    When the Synchronous option is selected, the administrator can define the number of links that should be processed asynchronously.

    It is not necessary to inform the editor when this occurs.

  • 🇬🇧United Kingdom ghazlewood

    Until this issue is resolved I think there should also be a warning on the module homepage that "Recalculate dependencies using queue" should be used in production.

  • First commit to issue fork.
  • Pipeline finished with Failed
    12 days ago
    Total: 172s
    #530078
  • Pipeline finished with Failed
    12 days ago
    Total: 178s
    #530320
  • Pipeline finished with Failed
    12 days ago
    Total: 183s
    #530355
  • Pipeline finished with Failed
    12 days ago
    Total: 1291s
    #530548
  • Pipeline finished with Failed
    12 days ago
    #530573
  • Pipeline finished with Success
    12 days ago
    Total: 350s
    #530592
  • Pipeline finished with Success
    12 days ago
    Total: 362s
    #530600
  • Pipeline finished with Failed
    12 days ago
    Total: 267s
    #530613
  • Pipeline finished with Success
    12 days ago
    Total: 314s
    #530620
  • Pipeline finished with Success
    12 days ago
    #530622
  • Pipeline finished with Success
    12 days ago
    Total: 220s
    #530627
  • 🇪🇸Spain Juanjol Navarra

    I have implemented the solution on comment #4; these are the changes in MR:

    Processing Modes:
    - Replaced process_mesh_using_queue checkbox with two radio button options:
    - Asynchronous (default): All dependencies queued for background processing
    - Synchronous: Smart processing based on dependency count
    - Added synchronous_limit field (default: 25) for synchronous mode threshold

    Processing Logic:
    - Entities with dependencies ≤ limit: Process immediately
    - Entities with dependencies > limit: Queue to prevent timeouts
    - New countEntityLinks() method counts dependencies without full processing

    Configuration Migration:
    - Update hook 10012 migrates old configuration to new structure
    - Removes deprecated process_mesh_using_queue setting

    Tests
    - Added kernel tests for processing mode logic
    - Added functional tests for settings form

    Moving to needs review!

  • Pipeline finished with Failed
    12 days ago
    Total: 394s
    #530848
  • 🇪🇸Spain Juanjol Navarra

    I have fixed too a bug found in the countEntityLinks() method where self-referencing links were being included in the dependency count. The getTargetLinks() method was counting the current entity's own canonical URL as a dependency link. This has been fixed by filtering out the entity's own URL from the target links array before counting. This ensures that entities don't incorrectly inflate their dependency count with self-references, providing more accurate threshold calculations for the synchronous/asynchronous processing logic.

  • Pipeline finished with Failed
    12 days ago
    Total: 176s
    #530893
  • Pipeline finished with Success
    12 days ago
    Total: 336s
    #530898
  • 🇪🇸Spain lpeidro Madrid

    Hello Juanjo,

    Great contribution once again—it's very valuable.

    Just a comment regarding how many times the getFullEntityDom method can be executed for the same entity. First, it is run in the countEntityLinks method. If the count does not exceed the limit, the entity is processed again in the setTargetsInSourceFromEntityRender method.

    It might be possible to implement a way to keep the DOM in memory to avoid regenerating it just a few lines later. A simple approach could be to use a static variable inside the getFullEntityDom method. Then, during the second execution, rendering the entity would not be necessary.

    Or perhaps this optimization is not needed if the resource impact is minimal. What do you think?

Production build 0.71.5 2024