Skip to content
Snippets Groups Projects
Commit 1bdb6ed2 authored by catch's avatar catch
Browse files

Issue #3394062 by ReINFaTe: Fiber loops in Renderer and BigPipe are never suspended

parent 53beb854
No related branches found
No related tags found
41 merge requests!8528Issue #3456871 by Tim Bozeman: Support NULL services,!8323Fix source code editing and in place front page site studio editing.,!6278Issue #3187770 by godotislate, smustgrave, catch, quietone: Views Rendered...,!54479.5.x SF update,!5022Issue #3394406: FileUploadHandler::handleExtensionValidation does not have fallback for sites still using file_validate_extensions,!3878Removed unused condition head title for views,!38582585169-10.1.x,!3818Issue #2140179: $entity->original gets stale between updates,!3742Issue #3328429: Create item list field formatter for displaying ordered and unordered lists,!3731Claro: role=button on status report items,!3668Resolve #3347842 "Deprecate the trusted",!3651Issue #3347736: Create new SDC component for Olivero (header-search),!3546refactored dialog.pcss file,!3531Issue #3336994: StringFormatter always displays links to entity even if the user in context does not have access,!3502Issue #3335308: Confusing behavior with FormState::setFormState and FormState::setMethod,!3452Issue #3332701: Refactor Claro's tablesort-indicator stylesheet,!3451Issue #2410579: Allows setting the current language programmatically.,!3355Issue #3209129: Scrolling problems when adding a block via layout builder,!3226Issue #2987537: Custom menu link entity type should not declare "bundle" entity key,!3154Fixes #2987987 - CSRF token validation broken on routes with optional parameters.,!3147Issue #3328457: Replace most substr($a, $i) where $i is negative with str_ends_with(),!3146Issue #3328456: Replace substr($a, 0, $i) with str_starts_with(),!3133core/modules/system/css/components/hidden.module.css,!31312878513-10.1.x,!2964Issue #2865710 : Dependencies from only one instance of a widget are used in display modes,!2812Issue #3312049: [Followup] Fix Drupal.Commenting.FunctionComment.MissingReturnType returns for NULL,!2614Issue #2981326: Replace non-test usages of \Drupal::logger() with IoC injection,!2378Issue #2875033: Optimize joins and table selection in SQL entity query implementation,!2334Issue #3228209: Add hasRole() method to AccountInterface,!2062Issue #3246454: Add weekly granularity to views date sort,!1255Issue #3238922: Refactor (if feasible) uses of the jQuery serialize function to use vanillaJS,!1105Issue #3025039: New non translatable field on translatable content throws error,!1073issue #3191727: Focus states on mobile second level navigation items fixed,!10223132456: Fix issue where views instances are emptied before an ajax request is complete,!877Issue #2708101: Default value for link text is not saved,!844Resolve #3036010 "Updaters",!673Issue #3214208: FinishResponseSubscriber could create duplicate headers,!617Issue #3043725: Provide a Entity Handler for user cancelation,!579Issue #2230909: Simple decimals fail to pass validation,!560Move callback classRemove outside of the loop,!555Issue #3202493
Pipeline #36490 failed
Pipeline: drupal

#36497

    Pipeline: drupal

    #36496

      Pipeline: drupal

      #36495

        +1
        ......@@ -708,8 +708,8 @@ protected function replacePlaceholders(array &$elements) {
        });
        }
        }
        $iterations = 0;
        while (count($fibers) > 0) {
        $iterations = 0;
        foreach ($fibers as $placeholder => $fiber) {
        if (!$fiber->isStarted()) {
        $fiber->start();
        ......
        ......@@ -553,8 +553,8 @@ protected function sendPlaceholders(array $placeholders, array $placeholder_orde
        }
        $fibers[$placeholder_id] = new \Fiber(fn() => $this->renderPlaceholder($placeholder_id, $placeholder_render_array));
        }
        $iterations = 0;
        while (count($fibers) > 0) {
        $iterations = 0;
        foreach ($fibers as $placeholder_id => $fiber) {
        // Keep skipping the messages placeholder until it's the only Fiber
        // remaining. @todo https://www.drupal.org/project/drupal/issues/3379885
        ......
        <?php
        namespace Drupal\Tests\big_pipe\Unit\Render;
        use Drupal\big_pipe\Render\BigPipe;
        use Drupal\big_pipe\Render\BigPipeResponse;
        use Drupal\Core\Config\ConfigFactoryInterface;
        use Drupal\Core\Controller\ControllerResolverInterface;
        use Drupal\Core\Render\ElementInfoManagerInterface;
        use Drupal\Core\Render\HtmlResponse;
        use Drupal\Core\Render\PlaceholderGeneratorInterface;
        use Drupal\Core\Render\RenderCacheInterface;
        use Drupal\Core\Render\Renderer;
        use Drupal\Core\Security\TrustedCallbackInterface;
        use Drupal\Core\Theme\ThemeManagerInterface;
        use Drupal\Tests\UnitTestCase;
        use Symfony\Component\HttpFoundation\Request;
        use Symfony\Component\HttpFoundation\RequestStack;
        use Symfony\Component\HttpFoundation\Session\SessionInterface;
        use Symfony\Component\HttpKernel\HttpKernelInterface;
        use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
        /**
        * @coversDefaultClass \Drupal\big_pipe\Render\BigPipe
        * @group big_pipe
        */
        class FiberPlaceholderTest extends UnitTestCase {
        /**
        * @covers \Drupal\big_pipe\Render\BigPipe::sendPlaceholders
        */
        public function testLongPlaceholderFiberSuspendingLoop() {
        $request_stack = $this->prophesize(RequestStack::class);
        $request_stack->getMainRequest()
        ->willReturn(new Request());
        $request_stack->getCurrentRequest()
        ->willReturn(new Request());
        $renderer = new Renderer(
        $this->prophesize(ControllerResolverInterface::class)->reveal(),
        $this->prophesize(ThemeManagerInterface::class)->reveal(),
        $this->prophesize(ElementInfoManagerInterface::class)->reveal(),
        $this->prophesize(PlaceholderGeneratorInterface::class)->reveal(),
        $this->prophesize(RenderCacheInterface::class)->reveal(),
        $request_stack->reveal(),
        [
        'required_cache_contexts' => [
        'languages:language_interface',
        'theme',
        ],
        ]
        );
        $session = $this->prophesize(SessionInterface::class);
        $session->start()->willReturn(TRUE);
        $bigpipe = new BigPipe(
        $renderer,
        $session->reveal(),
        $request_stack->reveal(),
        $this->prophesize(HttpKernelInterface::class)->reveal(),
        $this->createMock(EventDispatcherInterface::class),
        $this->prophesize(ConfigFactoryInterface::class)->reveal(),
        );
        $response = new BigPipeResponse(new HtmlResponse());
        $attachments = [
        'library' => [],
        'drupalSettings' => [
        'ajaxPageState' => [],
        ],
        'big_pipe_placeholders' => [
        'callback=%5CDrupal%5CTests%5Cbig_pipe%5CUnit%5CRender%5CTurtleLazyBuilder%3A%3Aturtle&amp;&amp;token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU' => [
        '#lazy_builder' => [
        '\Drupal\Tests\big_pipe\Unit\Render\TurtleLazyBuilder::turtle',
        [],
        ],
        ],
        ],
        ];
        $response->setAttachments($attachments);
        // Construct minimal HTML response.
        $content = '<html><body><span data-big-pipe-placeholder-id="callback=%5CDrupal%5CTests%5Cbig_pipe%5CUnit%5CRender%5CTurtleLazyBuilder%3A%3Aturtle&amp;&amp;token=uhKFNfT4eF449_W-kDQX8E5z4yHyt0-nSHUlwaGAQeU"></body></html>';
        $response->setContent($content);
        // Capture the result to avoid PHPUnit complaining.
        ob_start();
        $fiber = new \Fiber(function () use ($bigpipe, $response) {
        $bigpipe->sendContent($response);
        });
        $fiber->start();
        $this->assertFalse($fiber->isTerminated(), 'Placeholder fibers with long execution time supposed to return control before terminating');
        ob_get_clean();
        }
        }
        class TurtleLazyBuilder implements TrustedCallbackInterface {
        /**
        * #lazy_builder callback.
        *
        * Suspends its own execution twice to simulate long operation.
        *
        * @return array
        */
        public static function turtle(): array {
        if (\Fiber::getCurrent() !== NULL) {
        \Fiber::suspend();
        }
        if (\Fiber::getCurrent() !== NULL) {
        \Fiber::suspend();
        }
        return [
        '#markup' => '<span>Turtle is finally here. But how?</span>',
        ];
        }
        /**
        * {@inheritdoc}
        */
        public static function trustedCallbacks() {
        return ['turtle'];
        }
        }
        • catch @catch

          mentioned in commit 4456b257

          ·

          mentioned in commit 4456b257

          Toggle commit list
        0% Loading or .
        You are about to add 0 people to the discussion. Proceed with caution.
        Finish editing this message first!
        Please register or to comment