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

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