vendor/bref/symfony-bridge/src/BrefKernel.php line 48

Open in your IDE?
  1. <?php declare(strict_types=1);
  2. namespace Bref\SymfonyBridge;
  3. use Symfony\Component\Filesystem\Filesystem;
  4. use Symfony\Component\HttpFoundation\Response;
  5. use Symfony\Component\HttpKernel\HttpKernelInterface;
  6. use Symfony\Component\HttpKernel\Kernel;
  7. abstract class BrefKernel extends Kernel
  8. {
  9.     public function isLambda(): bool
  10.     {
  11.         return getenv('LAMBDA_TASK_ROOT') !== false;
  12.     }
  13.     public function getCacheDir(): string
  14.     {
  15.         if ($this->isLambda()) {
  16.             return '/tmp/cache/' $this->environment;
  17.         }
  18.         return parent::getCacheDir();
  19.     }
  20.     public function getLogDir(): string
  21.     {
  22.         if ($this->isLambda()) {
  23.             return '/tmp/log/';
  24.         }
  25.         return parent::getLogDir();
  26.     }
  27.     /**
  28.      * {@inheritDoc}
  29.      *
  30.      * When on the lambda, copy the cache dir over to /tmp where it is writable
  31.      * We have to do this before Symfony does anything else with the Kernel
  32.      * otherwise it might prematurely warm the cache before we can copy it
  33.      *
  34.      * @see https://github.com/brefphp/symfony-bridge/pull/37
  35.      */
  36.     public function handle($request$type HttpKernelInterface::MASTER_REQUEST$catch true): Response
  37.     {
  38.         $this->prepareCacheDir(parent::getCacheDir(), $this->getCacheDir());
  39.         return parent::handle($request$type$catch);
  40.     }
  41.     /**
  42.      * {@inheritdoc}
  43.      *
  44.      * We also need to prepare the Cache dir in Kernel::boot in case we are in a Console or worker context
  45.      * in which Kernel::handle is not called.
  46.      */
  47.     public function boot(): void
  48.     {
  49.         $this->prepareCacheDir(parent::getCacheDir(), $this->getCacheDir());
  50.         $this->ensureLogDir($this->getLogDir());
  51.         parent::boot();
  52.     }
  53.     /**
  54.      * Return the pre-warmed directories in var/cache/[env] that should be copied to
  55.      * a writable directory in the Lambda environment.
  56.      *
  57.      * For optimal performance one should prewarm the cache folder and override this
  58.      * function to return an empty array.
  59.      */
  60.     protected function getWritableCacheDirectories(): array
  61.     {
  62.         return ['pools'];
  63.     }
  64.     protected function prepareCacheDir(string $readOnlyDirstring $writeDir): void
  65.     {
  66.         if (! $this->isLambda() || is_dir($writeDir) || ! is_dir($readOnlyDir)) {
  67.             return;
  68.         }
  69.         $startTime microtime(true);
  70.         $cacheDirectoriesToCopy $this->getWritableCacheDirectories();
  71.         $filesystem = new Filesystem;
  72.         $filesystem->mkdir($writeDir);
  73.         $scandir scandir($readOnlyDirSCANDIR_SORT_NONE);
  74.         if ($scandir === false) {
  75.             return;
  76.         }
  77.         foreach ($scandir as $item) {
  78.             if (in_array($item, ['.''..'])) {
  79.                 continue;
  80.             }
  81.             // Copy directories to a writable space on Lambda.
  82.             if (in_array($item$cacheDirectoriesToCopy)) {
  83.                 $filesystem->mirror("$readOnlyDir/$item""$writeDir/$item");
  84.                 continue;
  85.             }
  86.             // Symlink all other directories
  87.             // This is especially important with the Container* directories since it uses require_once statements
  88.             if (is_dir("$readOnlyDir/$item")) {
  89.                 $filesystem->symlink("$readOnlyDir/$item""$writeDir/$item");
  90.                 continue;
  91.             }
  92.             // Copy all other files.
  93.             $filesystem->copy("$readOnlyDir/$item""$writeDir/$item");
  94.         }
  95.         $this->logToStderr(sprintf(
  96.             'Symfony cache directory prepared in %s ms.',
  97.             number_format((microtime(true) - $startTime) * 10002)
  98.         ));
  99.     }
  100.     /**
  101.      * Even though applications should never write into it on Lambda, there are parts of Symfony
  102.      * (like "about" CLI command) that expect the log dir exists, so we have to make sure of it.
  103.      *
  104.      * @see https://github.com/brefphp/symfony-bridge/issues/42
  105.      */
  106.     private function ensureLogDir(string $writeLogDir): void
  107.     {
  108.         if (! $this->isLambda() || is_dir($writeLogDir)) {
  109.             return;
  110.         }
  111.         $filesystem = new Filesystem;
  112.         $filesystem->mkdir($writeLogDir);
  113.     }
  114.     /**
  115.      * This method logs to stderr.
  116.      *
  117.      * It must only be used in a lambda environment since all error output will be logged.
  118.      *
  119.      * @param string $message The message to log
  120.      */
  121.     protected function logToStderr(string $message): void
  122.     {
  123.         file_put_contents('php://stderr'date('[c] ') . $message PHP_EOLFILE_APPEND);
  124.     }
  125. }