ai_upgrade_assistant-0.2.0-alpha2/src/Service/UpdateCronService.php

src/Service/UpdateCronService.php
<?php

namespace Drupal\ai_upgrade_assistant\Service;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\State\StateInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Queue\QueueFactory;
use Drupal\Core\Queue\QueueInterface;
use Drupal\Core\Datetime\DrupalDateTime;

/**
 * Service for managing scheduled updates via cron.
 */
class UpdateCronService {

  /**
   * The queue for processing updates.
   *
   * @var \Drupal\Core\Queue\QueueInterface
   */
  protected $queue;

  /**
   * The update scheduler service.
   *
   * @var \Drupal\ai_upgrade_assistant\Service\UpdateSchedulerService
   */
  protected $scheduler;

  /**
   * The update monitor service.
   *
   * @var \Drupal\ai_upgrade_assistant\Service\UpdateMonitorService
   */
  protected $monitor;

  /**
   * The update history service.
   *
   * @var \Drupal\ai_upgrade_assistant\Service\UpdateHistoryService
   */
  protected $history;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $config;

  /**
   * The state service.
   *
   * @var \Drupal\Core\State\StateInterface
   */
  protected $state;

  /**
   * The logger factory.
   *
   * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
   */
  protected $loggerFactory;

  /**
   * The logger channel.
   *
   * @var \Drupal\Core\Logger\LoggerChannelInterface
   */
  protected $logger;

  /**
   * Constructs a new UpdateCronService.
   *
   * @param \Drupal\Core\Queue\QueueFactory $queue_factory
   *   The queue factory.
   * @param \Drupal\ai_upgrade_assistant\Service\UpdateSchedulerService $scheduler
   *   The update scheduler service.
   * @param \Drupal\ai_upgrade_assistant\Service\UpdateMonitorService $monitor
   *   The update monitor service.
   * @param \Drupal\ai_upgrade_assistant\Service\UpdateHistoryService $history
   *   The update history service.
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Drupal\Core\State\StateInterface $state
   *   The state service.
   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
   *   The logger factory service.
   */
  public function __construct(
    QueueFactory $queue_factory,
    UpdateSchedulerService $scheduler,
    UpdateMonitorService $monitor,
    UpdateHistoryService $history,
    ConfigFactoryInterface $config_factory,
    StateInterface $state,
    LoggerChannelFactoryInterface $logger_factory
  ) {
    $this->queue = $queue_factory->get('ai_upgrade_assistant_updates');
    $this->scheduler = $scheduler;
    $this->monitor = $monitor;
    $this->history = $history;
    $this->config = $config_factory;
    $this->state = $state;
    $this->loggerFactory = $logger_factory;
    $this->logger = $logger_factory->get('ai_upgrade_assistant');
  }

  /**
   * Processes scheduled updates during cron run.
   */
  public function processCron() {
    // Check if we're within the allowed update window
    if (!$this->isWithinUpdateWindow()) {
      $this->logger->info('Outside of configured update window. Skipping updates.');
      return;
    }

    // Get scheduled updates that are ready to run
    $updates = $this->scheduler->getReadyUpdates();
    if (empty($updates)) {
      $this->logger->info('No updates ready to be processed.');
      return;
    }

    foreach ($updates as $update) {
      // Check if we're already processing this update
      if ($this->isUpdateInProgress($update)) {
        continue;
      }

      // Queue the update for processing
      $this->queueUpdate($update);
    }

    // Process security updates immediately if configured
    $config = $this->config->get('ai_upgrade_assistant.settings');
    if ($config->get('process_security_updates_immediately')) {
      $this->processSecurityUpdates();
    }
  }

  /**
   * Checks if current time is within the configured update window.
   *
   * @return bool
   *   TRUE if within update window, FALSE otherwise.
   */
  protected function isWithinUpdateWindow() {
    $config = $this->config->get('ai_upgrade_assistant.settings');
    $window_start = $config->get('update_window_start') ?: '00:00';
    $window_end = $config->get('update_window_end') ?: '23:59';
    
    $current_time = new DrupalDateTime();
    $current_hour = $current_time->format('H:i');
    
    // Handle window crossing midnight
    if ($window_start > $window_end) {
      return $current_hour >= $window_start || $current_hour <= $window_end;
    }
    
    return $current_hour >= $window_start && $current_hour <= $window_end;
  }

  /**
   * Checks if an update is already in progress.
   *
   * @param array $update
   *   The update to check.
   *
   * @return bool
   *   TRUE if update is in progress, FALSE otherwise.
   */
  protected function isUpdateInProgress(array $update) {
    $in_progress = $this->state->get('ai_upgrade_assistant.updates_in_progress', []);
    $key = $update['module_name'] . '-' . $update['to_version'];
    
    if (isset($in_progress[$key])) {
      // Check if the update has been stuck for too long
      $timeout = $this->config->get('ai_upgrade_assistant.settings')
        ->get('update_timeout') ?: 3600; // Default 1 hour
      
      if ((time() - $in_progress[$key]) > $timeout) {
        // Clear the stuck update
        unset($in_progress[$key]);
        $this->state->set('ai_upgrade_assistant.updates_in_progress', $in_progress);
        return FALSE;
      }
      
      return TRUE;
    }
    
    return FALSE;
  }

  /**
   * Queues an update for processing.
   *
   * @param array $update
   *   The update to queue.
   */
  protected function queueUpdate(array $update) {
    // Mark update as in progress
    $in_progress = $this->state->get('ai_upgrade_assistant.updates_in_progress', []);
    $key = $update['module_name'] . '-' . $update['to_version'];
    $in_progress[$key] = time();
    $this->state->set('ai_upgrade_assistant.updates_in_progress', $in_progress);

    // Record update start in history
    $update_id = $this->history->recordUpdateStart(
      $update['module_name'],
      $update['from_version'],
      $update['to_version'],
      [
        'complexity' => $update['complexity'] ?? 'unknown',
        'security_update' => $update['security_update'] ?? FALSE,
        'estimated_duration' => $update['estimated_duration'] ?? NULL,
      ]
    );

    // Add to queue
    $this->queue->createItem([
      'update' => $update,
      'update_id' => $update_id,
    ]);

    $this->logger->info(
      'Queued update for @module from @from to @to',
      [
        '@module' => $update['module_name'],
        '@from' => $update['from_version'],
        '@to' => $update['to_version'],
      ]
    );
  }

  /**
   * Processes security updates immediately.
   */
  protected function processSecurityUpdates() {
    $security_updates = $this->monitor->getSecurityUpdates();
    foreach ($security_updates as $update) {
      if (!$this->isUpdateInProgress($update)) {
        $this->queueUpdate($update);
      }
    }
  }

}

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

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