Commit 2ba39992 authored by Adam G-H's avatar Adam G-H
Browse files

Issue #3277014 by phenaproxima, lhridley, p.ayekumi, capysara, percoction:...

Issue #3277014 by phenaproxima, lhridley, p.ayekumi, capysara, percoction: Increase timeouts during create and apply
parent ab57f234
Loading
Loading
Loading
Loading
+14 −4
Original line number Diff line number Diff line
@@ -238,6 +238,11 @@ class Stage {
   * call ::claim(). However, if it was created during another request, the
   * stage must be claimed before operations can be performed on it.
   *
   * @param int|null $timeout
   *   (optional) How long to allow the file copying operation to run before
   *   timing out, in seconds, or NULL to never time out. Defaults to 300
   *   seconds.
   *
   * @return string
   *   Unique ID for the stage, which can be used to claim the stage before
   *   performing other operations on it. Calling code should store this ID for
@@ -248,7 +253,7 @@ class Stage {
   *
   * @see ::claim()
   */
  public function create(): string {
  public function create(?int $timeout = 300): string {
    if (!$this->isAvailable()) {
      throw new StageException('Cannot create a new stage because one already exists.');
    }
@@ -270,7 +275,7 @@ class Stage {
    // available.
    $this->dispatch($event, [$this, 'markAsAvailable']);

    $this->beginner->begin($active_dir, $stage_dir, $event->getExcludedPaths());
    $this->beginner->begin($active_dir, $stage_dir, $event->getExcludedPaths(), NULL, $timeout);
    $this->dispatch(new PostCreateEvent($this));
    return $id;
  }
@@ -313,8 +318,13 @@ class Stage {

  /**
   * Applies staged changes to the active directory.
   *
   * @param int|null $timeout
   *   (optional) How long to allow the file copying operation to run before
   *   timing out, in seconds, or NULL to never time out. Defaults to 600
   *   seconds.
   */
  public function apply(): void {
  public function apply(?int $timeout = 600): void {
    $this->checkOwnership();

    $active_dir = $this->pathLocator->getProjectRoot();
@@ -331,7 +341,7 @@ class Stage {
    $this->tempStore->set(self::TEMPSTORE_APPLY_TIME_KEY, $this->time->getRequestTime());
    $this->dispatch($event, $release_apply);

    $this->committer->commit($stage_dir, $active_dir, $event->getExcludedPaths());
    $this->committer->commit($stage_dir, $active_dir, $event->getExcludedPaths(), NULL, $timeout);

    // Rebuild the container and clear all caches, to ensure that new services
    // are picked up.
+1 −1
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@ class Beginner extends InvocationRecorderBase implements BeginnerInterface {
   * {@inheritdoc}
   */
  public function begin(string $activeDir, string $stagingDir, ?array $exclusions = [], ?OutputCallbackInterface $callback = NULL, ?int $timeout = 120): void {
    $this->saveInvocationArguments($activeDir, $stagingDir, $exclusions);
    $this->saveInvocationArguments($activeDir, $stagingDir, $exclusions, $timeout);
  }

}
+1 −1
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@ class Committer extends InvocationRecorderBase implements CommitterInterface {
   * {@inheritdoc}
   */
  public function commit(string $stagingDir, string $activeDir, ?array $exclusions = [], ?OutputCallbackInterface $callback = NULL, ?int $timeout = 120): void {
    $this->saveInvocationArguments($activeDir, $stagingDir, $exclusions);
    $this->saveInvocationArguments($stagingDir, $activeDir, $exclusions, $timeout);
  }

  /**
+24 −0
Original line number Diff line number Diff line
@@ -208,6 +208,30 @@ class StageTest extends PackageManagerKernelTestBase {
    $stage->apply();
  }

  /**
   * Tests that Composer Stager is invoked with a long timeout.
   */
  public function testTimeouts(): void {
    $stage = $this->createStage();
    $stage->create(420);
    $stage->apply();

    $timeouts = [
      // The beginner was given an explicit timeout.
      'package_manager.beginner' => 420,
      // The committer should have been called with a longer timeout than
      // Composer Stager's default of 120 seconds.
      'package_manager.committer' => 600,
    ];
    foreach ($timeouts as $service_id => $expected_timeout) {
      $invocations = $this->container->get($service_id)->getInvocationArguments();

      // The service should have been called with the expected timeout.
      $this->assertCount(1, $invocations);
      $this->assertSame($expected_timeout, end($invocations[0]));
    }
  }

}

/**
+12 −6
Original line number Diff line number Diff line
@@ -76,15 +76,20 @@ class CronUpdater extends Updater {

  /**
   * Handles updates during cron.
   *
   * @param int|null $timeout
   *   (optional) How long to allow the file copying operation to run before
   *   timing out, in seconds, or NULL to never time out. Defaults to 300
   *   seconds.
   */
  public function handleCron(): void {
  public function handleCron(?int $timeout = 300): void {
    if ($this->getMode() === static::DISABLED) {
      return;
    }

    $next_release = $this->releaseChooser->getLatestInInstalledMinor();
    if ($next_release) {
      $this->performUpdate($next_release->getVersion());
      $this->performUpdate($next_release->getVersion(), $timeout);
    }
  }

@@ -93,8 +98,11 @@ class CronUpdater extends Updater {
   *
   * @param string $update_version
   *   The version to which to update.
   * @param int|null $timeout
   *   How long to allow the operation to run before timing out, in seconds, or
   *   NULL to never time out.
   */
  private function performUpdate(string $update_version): void {
  private function performUpdate(string $update_version, ?int $timeout): void {
    $installed_version = (new ProjectInfo('drupal'))->getInstalledVersion();
    if (empty($installed_version)) {
      $this->logger->error('Unable to determine the current version of Drupal core.');
@@ -105,9 +113,7 @@ class CronUpdater extends Updater {
    // handle any exceptions or validation errors consistently, and destroy the
    // stage regardless of whether the update succeeds.
    try {
      $this->begin([
        'drupal' => $update_version,
      ]);
      $this->begin(['drupal' => $update_version], $timeout);
      $this->stage();
      $this->apply();

Loading