drupalorg-1.0.x-dev/src/Plugin/QueueWorker/DrupalOrgIssueForksQueueWorker.php

src/Plugin/QueueWorker/DrupalOrgIssueForksQueueWorker.php
<?php

namespace Drupal\drupalorg\Plugin\QueueWorker;

use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\Queue\QueueWorkerBase;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\drupalorg\Traits\GitLabClientTrait;
use Drupal\drupalorg\UserService;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * Defines 'drupalorg_issue_forks_queue_worker' queue worker.
 *
 * Run via `drush` like this:
 * `drush queue:run drupalorg_issue_forks_queue_worker`.
 *
 * @QueueWorker(
 *   id = "drupalorg_issue_forks_queue_worker",
 *   title = @Translation("Issue Forks Queue Worker")
 * )
 */
class DrupalOrgIssueForksQueueWorker extends QueueWorkerBase implements ContainerFactoryPluginInterface {

  use GitLabClientTrait;
  use StringTranslationTrait;

  /**
   * Number of attempts to retry post fork actions.
   *
   * @var int
   */
  const POST_FORK_ACTIONS_ATTEMPTS = 20;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $configuration,
      $plugin_id,
      $plugin_definition,
      $container->get('drupalorg.user_service'),
      $container->get('logger.factory')->get('drupalorg'),
      $container->get('queue')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function __construct(
    array $configuration,
    $plugin_id,
    $plugin_definition,
    protected UserService $userService,
    protected LoggerInterface $logger,
    protected QueueFactory $queueFactory,
  ) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);
  }

  /**
   * {@inheritdoc}
   */
  public function processItem($data) {
    if (!$this->validateItem($data)) {
      return FALSE;
    }

    switch ($data['action']) {
      case 'post_fork_creation':
        $this->postForkCreation($data);
        break;
    }
  }

  /**
   * Validate item array to make sure all key elements are there.
   *
   * @param array $data
   *   Item to validate.
   *
   * @return bool
   *   Whether the item was valid or not.
   */
  protected function validateItem(array $data) {
    if (
      empty($data['action']) ||
      empty($data['fork_id']) ||
      empty($data['issue_id']) ||
      empty($data['user_id'])
    ) {
      return FALSE;
    }

    return TRUE;
  }

  /**
   * Creates a branch based on the issue id and adds the user as member.
   *
   * @param array $data
   *   Data given to the queue containing user, issue and fork information.
   */
  protected function postForkCreation(array $data) {
    $client = $this->getGitLabClient();

    try {
      $fork = $client->projects()->show($data['fork_id']);

      // Was there any error in the fork creation?
      if (!empty($fork['import_error'])) {
        $this->logger->error('Import failed for @name: @import_error', [
          '@name' => $data['fork_id'],
          '@import_error' => $fork['import_error'],
        ]);
        throw new \Exception($this->t('Import failed for @name', [
          '@name' => $data['fork_id'],
        ]));
      }

      // Check status, make sure the fork is finished, otherwise requeue.
      if ($fork['import_status'] !== 'finished') {
        if (empty($data['attempts'])) {
          $data['attempts'] = 0;
        }
        $data['attempts']++;
        if ($data['attempts'] <= self::POST_FORK_ACTIONS_ATTEMPTS) {
          // Try again in this queue.
          $this->queueFactory->get('drupalorg_issue_forks_queue_worker')->createItem($data);
          $this->logger->warning('Import did not finish for @name: re-queue item attempt @attempt/@max.', [
            '@name' => $data['fork_id'],
            '@attempt' => $data['attempts'],
            '@max' => self::POST_FORK_ACTIONS_ATTEMPTS,
          ]);
        }
        else {
          // Limit exceeded, send to the delayed queue to give it a breather.
          $this->logger->error('Import did not finish for @name: max-attempts(@max) exceeded.', [
            '@name' => $data['fork_id'],
            '@max' => self::POST_FORK_ACTIONS_ATTEMPTS,
          ]);
          $data['delayed_at'] = strtotime('now');
          $data['queue'] = $this->getPluginId();
          $this->queueFactory->get('drupalorg_delayed_items_queue_worker')->createItem($data);
        }
        return;
      }

      // Create a branch with the issue number in it.
      if (!empty($data['source_branch']) && !empty($data['branch_name'])) {
        $client->repositories()->createBranch($data['fork_id'], $data['branch_name'], $data['source_branch']);
      }

      // Update forked project description and settings.
      $options = $this->getForkDefaultOptions();
      $options['description'] = 'For collaboration on ' . $data['issue_link'];
      $client->projects()->update($fork['id'], $options);
    }
    catch (\Throwable $e) {
      $this->logger->error('Error in post fork creation. Message: @message', [
        '@message' => $e->getMessage(),
      ]);
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc