Continous Jobs may result in endless loop when using content_translation_outdated flag

Created on 21 June 2019, about 6 years ago
Updated 23 June 2025, 19 days ago

Hello everyone,

We have a project in which we wanted to re-autotranslate to several languages when the base language changed, but only for published entities. A continous job was created, with google as the provider.

So we set in a presave() hook a to load and save translations while setting the 'content_translation_outdated' field via ContentTranslationMetadataWrapper::setOutdated()
(Instead of doing this manually, we also tried https://www.drupal.org/project/drupal/issues/2950627 📌 Make it easier for contrib to restore the "Flag as outdated" functionality for moderated content Postponed: needs info this patch which provides a checkbox to set this property via the UI)

This results in an endless loop since on in the function ContentEntitySource::shouldCreateContinuousItem

web/modules/contrib/tmgmt/sources/content/src/Plugin/tmgmt/Source/ContentEntitySource.php:473

    $translation = $entity->hasTranslation($job->getTargetLangcode()) ? $entity->getTranslation($job->getTargetLangcode()) : NULL;
    $metadata = isset($translation) ? $translation_manager->getTranslationMetadata($translation) : NULL;

    // If a translation exists and is not marked as outdated, no new job items
    // needs to be created.
    if (isset($translation) && !$metadata->isOutdated()) {
      return FALSE;
    }
    else {

it will continue to fail this check !$metadata->isOutdated() since the continous job won't reset 'content_translation_outdated'.

What happens is, that the newly created job item is created, the auto translation will succeed, and the node translation will be saved.
The custom presave hook will run but it won't do anything if the activeLanguage of the node is not the source language so this will pass.. But the tmgmt update hook will trigger, after the save of the node, and start the cycle anew, wanting to create a job item for the saved translation etc,..

🐛 Bug report
Status

Active

Version

1.8

Component

Core

Created by

🇦🇹Austria vierlex

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

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • achap 🇦🇺

    So I think this is actually a bug and not just with moderated entities. Initially I thought it was due to the referenced core bug (which is why marking revisions as outdated was hidden in the first place in core for moderated entities) but I was actually able to reproduce it for unmoderated entities too on a freshly installed site without any of my custom code.

    Steps to reproduce:

    1. Setup a fresh ddev instance of Drupal https://ddev.readthedocs.io/en/latest/users/quickstart/#drupal
    2. Require tmgmt with composer and install via drush.
    3. Enable the tmgmt_test module via drush so the test translator is available.
    4. Enable German as a language.
    5. Enable Spanish as a language
    6. Make the default article bundle translatable along with all fields
    7. Setup a continuous job for the article in German using test translator
    8. Setup a continuous job for the article in Spanish using test translator
    9. Create an article and save it
    10. Run the following SQL and you should see two inactive continuous jobs select tji.item_id, tji.tjiid, tj.target_language from tmgmt_job_item as tji join tmgmt_job as tj on tji.tjid = tj.tjid where tj.job_type = 'continuous' and tji.state = 'inactive';
    11. Run ddev drush php-eval "tmgmt_cron();" and then run the SQL above again and there should be no inactive job items.
    12. Go to the article in the original language and click mark translation as outdated then save it.
    13. Now if you run the SQL again there should be two inactive items
    14. Now run ddev drush php-eval "tmgmt_cron();" again and when you run your SQL you will see one job item remaining.

    Now matter how many times you run tmgmt_cron() via drush from there there is always one remaining inactive item and it alternates between de and es. It's like one is always marking the other as outdated.

    Would appreciate if someone else can confirm my steps to reproduce. Would potentially think about marking this as major if it's confirmed as this can cause a huge amount of revisions/costs from re translation.

    Versions: Drupal core 11.1.8, tmgmt 1.17.0

Production build 0.71.5 2024