0

We face a major problem for our client.

To put it in context, this is a Drupal 8 with commerce that has a large number of products that come from a PIM. To be clearer, the products are not managed in Drupal but, on the other hand, we have to import them into Drupal every night. This is mass import that lasts quite a long time, a complete import of all products can take up to 14h, a differential import usually takes 2h. The trouble is that recently we have come across a recurring timeout problem of 14400s. After some research, we found that the problem came from a modification of Drush that adds a timeout of 14400s by default.

After much research we can not figure out how to change this default timeout, would anyone have an idea?

Here is a link: https://github.com/drush-ops/drush/blob/d6ca80437f74a7428f002e3f956e47977d39a17a/src/Drush.php#L76

Edit: We have no idea how to change this timeout properly.

Without solution, we will return to a previous version of Drush or we will apply a patch to change the value directly.

Edit 2: Here is the code of the DrushCommands:

<?php

namespace Drupal\custom_product_import\Commands;

use Drush\Commands\DrushCommands;
use Drupal\maps_suite\Log\Logger;
use Drupal\maps_import\Log\Observer\Mail as MailObserver;
use Drupal\maps_suite\Log\Context\Context;

/**
 * A Drush commandfile.
 *
 * In addition to this file, you need a drush.services.yml
 * in root of your module, and a composer.json file that provides the name
 * of the services file to use.
 *
 * See these files for an example of injecting Drupal services:
 *   - http://cgit.drupalcode.org/devel/tree/src/Commands/DevelCommands.php
 *   - http://cgit.drupalcode.org/devel/tree/drush.services.yml
 */
class CustomProductImportCommands extends DrushCommands {

  /**
   * Process the given operation.
   *
   * @param $pid
   *   The MaPS Import profile id.
    * @param array $options An associative array of options whose values come from cli, aliases, config, etc.
   * @option op
   *   Specify the operations to process (separated by commas)
   * @option list
   *   List the available operations
   * @option diff
   *   Differential import
   * @option thread
   *   Specify the thread to process
   * @option process
   *   Specify the process id to process
   * @usage maps-import 1
   *   Process all available operations for the profile with the pid 1.
   * @usage maps-import 1 --op=library_mapping,objects_fetch
   *   Process the "objects_fetch" operation, then the "library_mapping" operation, in the right order.
   * @usage maps-import 1 --list
   *   List all the available operations for the profile with the pid 1
   *
   * @command custom:maps-import
   * @aliases cust-m-i,custom-maps-import
   */
  public function mapsImport($pid, array $options = ['op' => null, 'list' => null, 'diff' => null, 'thread' => null, 'process' => null]) {
    // See bottom of https://weitzman.github.io/blog/port-to-drush9 for details on what to change when porting a
    // legacy command.
    if (is_null($pid)) {
      echo "You must specify a profile id as first parameter.\n";
      return FALSE;
    }

    // Are the thread specified in the parameters?
    $thread = NULL;
    if ($options['thread']) {
      $thread = $options['thread'];
    }

    // Are the process specified in the parameters?
    $process = NULL;
    if ($options['process']) {
      $process = $options['process'];
    }

    if ($options['list']) {
      drush_maps_import_list($pid);
      return;
    }

    $vars = \Drupal::config('maps_import.settings');

    // Check if there is already operations processing.
    if ($vars->get('maps_import_lock')) {
      drush_set_error('maps_import_lock', 'There is already a running operation.');
      drush_die("\n");
    }

    $profile = _maps_import_profile_load($pid);
    $operations = maps_import_get_import_operations($profile);

    // Are the operations specified in the parameters?
    if ($ops = $options['op']) {
      $ops = array_map('trim', explode(',', $ops));

      // Check if all the given operations exist.
      if ($invalid = array_diff($ops, array_keys($operations))) {
        echo 'The following operations are not defined: ' . implode(', ', $invalid) . "\n";
        return FALSE;
      }

      // Update the $operations variables with the specified operations.
      $operations = array_intersect_key($operations, array_flip($ops));
    }

    // Set up lock.
    \Drupal::configFactory()
      ->getEditable('maps_import.settings')
      ->set('maps_import_lock', 1)
      ->save();

    // Differential call.
    if ($options['diff']) {
      // Check if we can process the differential call.
      if ($profile->getOptionsItem('differential') && $vars->get('maps_import:configuration_full:' . $profile->getPid()) && $vars->get('maps_import:objects_full:' . $profile->getPid())) {
        \Drupal::configFactory()
          ->getEditable('maps_import.settings')
          ->set('maps_import_differential', 1)
          ->save();
      }
    }

    // Process chosen operations.
    $batch_operations = array();
    foreach ($operations as $name => $operation) {
      printf($operation['title'] . "\n");
      if ($operation['class'] == 'Drupal\custom_product_import\CustomProductImportMapping\CustomProductMapping') {
        $op = new $operation['class']($profile, $thread, $process);
      } else {
        $op = new $operation['class']($profile);
      }
      $batch_operations = array_merge($batch_operations, $op->batchOperations());
    }

    $batch = array(
      'operations'          => $batch_operations,
      'title'               => t('Update for the profile %title', array('%title' => $profile->getTitle())),
      'finished'            => '\Drupal\custom_product_import\CustomProductImportMapping\CustomProductMapping::ImportFinished',
      'maps_import_profile' => $profile->id()
    );

    batch_set($batch);
    drush_backend_batch_process();
  }
}
  • 1
    The comments say Can be customized via setTimeout() method., have you tugged at that thread at all? – Clive May 7 at 8:08
  • No I see the comments but when I'm in DrushCommands, I don't find how I can reach this function setTimeout() ... – Guillaume Horsin May 7 at 11:58
  • Please share code of your command. – moshe weitzman May 9 at 9:45
  • I edit my post to add the commands. – Guillaume Horsin May 9 at 11:19
  • @GuillaumeHorsin Hi, did you figure out how to change timeout value? – tasqyn Oct 15 at 6:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.