Issue #3414287 by catch, longwave: Avoid reading session from the database multiple times during a big pipe request

merge-requests/6724/merge
Alex Pott 2024-02-22 13:05:24 +00:00
parent 4e26ae9cc3
commit 213906e286
No known key found for this signature in database
GPG Key ID: BDA67E7EE836E5CE
6 changed files with 23 additions and 18 deletions

View File

@ -0,0 +1,16 @@
<?php
namespace Drupal\Core\Session;
/**
* Indicates that sessions for this response should be kept open after sending.
*
* By default, Drupal closes sessions as soon as the response is sent. If
* a response implements this interface, Drupal will skip this behavior and
* assume that the session will be closed manually later in the request.
*
* @see Drupal\Core\StackMiddleware\Session
* @see Drupal\big_pipe\src\Render\BigPipeResponse
* @internal
*/
interface ResponseKeepSessionOpenInterface {}

View File

@ -2,6 +2,7 @@
namespace Drupal\Core\StackMiddleware;
use Drupal\Core\Session\ResponseKeepSessionOpenInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@ -58,7 +59,7 @@ class Session implements HttpKernelInterface {
$result = $this->httpKernel->handle($request, $type, $catch);
if ($type === self::MAIN_REQUEST && PHP_SAPI !== 'cli' && $request->hasSession()) {
if ($type === self::MAIN_REQUEST && !$result instanceof ResponseKeepSessionOpenInterface && PHP_SAPI !== 'cli' && $request->hasSession()) {
$request->getSession()->save();
}

View File

@ -220,16 +220,6 @@ class BigPipe {
}
}
/**
* Performs tasks before sending content (and rendering placeholders).
*/
protected function performPreSendTasks() {
// The content in the placeholders may depend on the session, and by the
// time the response is sent (see index.php), the session is already
// closed. Reopen it for the duration that we are rendering placeholders.
$this->session->start();
}
/**
* Performs tasks after sending content (and rendering placeholders).
*/
@ -282,8 +272,6 @@ class BigPipe {
$cumulative_assets = AttachedAssets::createFromRenderArray(['#attached' => $attachments]);
$cumulative_assets->setAlreadyLoadedLibraries($attachments['library']);
$this->performPreSendTasks();
// Find the closing </body> tag and get the strings before and after. But be
// careful to use the latest occurrence of the string "</body>", to ensure
// that strings in inline JavaScript or CDATA sections aren't used instead.

View File

@ -3,6 +3,7 @@
namespace Drupal\big_pipe\Render;
use Drupal\Core\Render\HtmlResponse;
use Drupal\Core\Session\ResponseKeepSessionOpenInterface;
/**
* A response that is sent in chunks by the BigPipe service.
@ -18,7 +19,7 @@ use Drupal\Core\Render\HtmlResponse;
* created in https://www.drupal.org/node/2577631. Only code internal to
* BigPipe should instantiate or type hint to this class.
*/
class BigPipeResponse extends HtmlResponse {
class BigPipeResponse extends HtmlResponse implements ResponseKeepSessionOpenInterface {
/**
* The BigPipe service.

View File

@ -35,8 +35,7 @@ class OpenTelemetryAuthenticatedPerformanceTest extends PerformanceTestBase {
$performance_data = $this->collectPerformanceData(function () {
$this->drupalGet('<front>');
}, 'authenticatedFrontPage');
$this->assertGreaterThanOrEqual(10, $performance_data->getQueryCount());
$this->assertLessThanOrEqual(12, $performance_data->getQueryCount());
$this->assertCountBetween(9, 11, $performance_data->getQueryCount());
$this->assertSame(45, $performance_data->getCacheGetCount());
$this->assertSame(0, $performance_data->getCacheSetCount());
$this->assertSame(0, $performance_data->getCacheDeleteCount());

View File

@ -113,7 +113,7 @@ class StandardPerformanceTest extends PerformanceTestBase {
$this->submitLoginForm($account);
});
$this->assertCountBetween(26, 31, $performance_data->getQueryCount());
$this->assertCountBetween(25, 30, $performance_data->getQueryCount());
$this->assertSame(64, $performance_data->getCacheGetCount());
$this->assertSame(1, $performance_data->getCacheSetCount());
$this->assertSame(1, $performance_data->getCacheDeleteCount());
@ -146,7 +146,7 @@ class StandardPerformanceTest extends PerformanceTestBase {
$performance_data = $this->collectPerformanceData(function () use ($account) {
$this->submitLoginForm($account);
});
$this->assertCountBetween(31, 34, $performance_data->getQueryCount());
$this->assertCountBetween(30, 33, $performance_data->getQueryCount());
$this->assertSame(85, $performance_data->getCacheGetCount());
$this->assertSame(1, $performance_data->getCacheSetCount());
$this->assertSame(1, $performance_data->getCacheDeleteCount());