Skip to content

Commit

Permalink
Opcache Preloading Integration (#8192)
Browse files Browse the repository at this point in the history
* Preload.php Generator: Data Object / Field Collection / Object Bricks class files - see #5387

* models & lib classes
  • Loading branch information
brusch committed Feb 17, 2021
1 parent 8644e90 commit 0c5613c
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 0 deletions.
5 changes: 5 additions & 0 deletions bundles/CoreBundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ services:
tags:
- { name: kernel.cache_warmer }

Pimcore\HttpKernel\CacheWarmer\PimcoreCoreCacheWarmer:
public: false
tags:
- { name: kernel.cache_warmer }

Pimcore\Cache\Symfony\CacheClearer:
public: true

Expand Down
120 changes: 120 additions & 0 deletions lib/HttpKernel/CacheWarmer/PimcoreCoreCacheWarmer.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
<?php
/**
* Pimcore
*
* This source file is available under two different licenses:
* - GNU General Public License version 3 (GPLv3)
* - Pimcore Enterprise License (PEL)
* Full copyright and license information is available in
* LICENSE.md which is distributed with this source code.
*
* @copyright Copyright (c) Pimcore GmbH (http://www.pimcore.org)
* @license http://www.pimcore.org/license GPLv3 and PEL
*/

namespace Pimcore\HttpKernel\CacheWarmer;

use Pimcore\Bootstrap;
use Pimcore\Model\Asset;
use Pimcore\Model\DataObject;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;

class PimcoreCoreCacheWarmer implements CacheWarmerInterface
{

/**
* @inheritDoc
*/
public function isOptional()
{
return true;
}

/**
* @inheritDoc
*/
public function warmUp($cacheDir)
{
$classes = [];

$this->libraryClasses($classes);
$this->modelClasses($classes);
$this->dataObjectClasses($classes);

return $classes;
}

private function libraryClasses(array &$classes): void
{
$excludePattern = '@/lib/(Migrations|Maintenance|Sitemap|Workflow|Console|Composer|Translation/(Import|Export)|Image/Optimizer|DataObject/(GridColumnConfig|Import)|Test|Tool/Transliteration|(Pimcore|simple_html_dom)\.php)@';

$reflection = new \ReflectionClass(Bootstrap::class);
$dir = dirname($reflection->getFileName());

$this->getClassesFromDirectory($dir, $excludePattern, 'Pimcore', $classes);
}

private function modelClasses(array &$classes): void
{
$excludePattern = '@/models/(GridConfig|ImportConfig|Notification|Schedule|Tool/CustomReport|User|Workflow)@';

$reflection = new \ReflectionClass(Asset::class);
$dir = dirname($reflection->getFileName());

$this->getClassesFromDirectory($dir, $excludePattern, 'Pimcore\Model', $classes);
}

private function getClassesFromDirectory(string $dir, string $excludePattern, string $NSPrefix, array &$classes): void
{
$files = rscandir($dir);

foreach($files as $file) {
$file = str_replace(DIRECTORY_SEPARATOR, '/', $file);
if(is_file($file) && !preg_match($excludePattern, $file)) {
$className = preg_replace('@^' . preg_quote($dir, '@') . '@', $NSPrefix, $file);
$className = preg_replace('@\.php$@', '', $className);
$className = str_replace(DIRECTORY_SEPARATOR, '\\', $className);

if(class_exists($className)) {
$classes[] = $className;
}
}
}
}

private function dataObjectClasses(array &$classes): void

This comment has been minimized.

Copy link
@dpfaffenbauer

dpfaffenbauer Feb 23, 2021

Contributor

data object classes might not exist when cache is loaded, result in following error:

 // Clearing the cache for the test environment with debug                      
 // true                                                                        

10:32:57 EMERGENCY [pimcore] PDOException: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'coreshop_test.classes' doesn't exist in /home/runner/work/CoreShop/CoreShop/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:125
Stack trace:
#0 /home/runner/work/CoreShop/CoreShop/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php(125): PDO->query()
#1 /home/runner/work/CoreShop/CoreShop/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOQueryImplementation.php(36): Doctrine\DBAL\Driver\PDOConnection->doQuery()
#2 /home/runner/work/CoreShop/CoreShop/vendor/doctrine/dbal/lib/Doctrine/DBAL/Connection.php(1260): Doctrine\DBAL\Driver\PDOConnection->query()
#3 /home/runner/work/CoreShop/CoreShop/vendor/pimcore/pimcore/lib/Db/PimcoreExtensionsTrait.php(94): Doctrine\DBAL\Connection->executeQuery()
#4 /home/runner/work/CoreShop/CoreShop/vendor/pimcore/pimcore/lib/Db/PimcoreExtensionsTrait.php(273): Pimcore\Db\Connection->executeQuery()
#5 /home/runner/work/CoreShop/CoreShop/vendor/pimcore/pimcore/models/DataObject/ClassDefinition/Listing/Dao.php(38): Pimcore\Db\Connection->fetchCol()
#6 [internal function]: Pimcore\Model\DataObject\ClassDefinition\Listing\Dao->load()
#7 /home/runner/work/CoreShop/CoreShop/vendor/pimcore/pimcore/lib/Model/AbstractModel.php(242): call_user_func_array()
#8 /home/runner/work/CoreShop/CoreShop/vendor/pimcore/pimcore/lib/HttpKernel/CacheWarmer/PimcoreCoreCacheWarmer.php(89): Pimcore\Model\AbstractModel->__call()
#9 /home/runner/work/CoreShop/CoreShop/vendor/pimcore/pimcore/lib/HttpKernel/CacheWarmer/PimcoreCoreCacheWarmer.php(41): Pimcore\HttpKernel\CacheWarmer\PimcoreCoreCacheWarmer->dataObjectClasses()
#10 /home/runner/work/CoreShop/CoreShop/vendor/symfony/symfony/src/Symfony/Component/HttpKernel/CacheWarmer/CacheWarmerAggregate.php(98): Pimcore\HttpKernel\CacheWarmer\PimcoreCoreCacheWarmer->warmUp()
#11 /home/runner/work/CoreShop/CoreShop/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Command/CacheClearCommand.php(142): Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate->warmUp()
#12 /home/runner/work/CoreShop/CoreShop/vendor/symfony/symfony/src/Symfony/Component/Console/Command/Command.php(256): Symfony\Bundle\FrameworkBundle\Command\CacheClearCommand->execute()
#13 /home/runner/work/CoreShop/CoreShop/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(989): Symfony\Component\Console\Command\Command->run()
#14 /home/runner/work/CoreShop/CoreShop/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php(96): Symfony\Component\Console\Application->doRunCommand()
#15 /home/runner/work/CoreShop/CoreShop/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(290): Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand()
#16 /home/runner/work/CoreShop/CoreShop/vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Console/Application.php(82): Symfony\Component\Console\Application->doRun()
#17 /home/runner/work/CoreShop/CoreShop/vendor/symfony/symfony/src/Symfony/Component/Console/Application.php(166): Symfony\Bundle\FrameworkBundle\Console\Application->doRun()
#18 /home/runner/work/CoreShop/CoreShop/bin/console(36): Symfony\Component\Console\Application->run()
#19 {main}

This comment has been minimized.

Copy link
@dpfaffenbauer

dpfaffenbauer Feb 23, 2021

Contributor

(table I meant)

{

// load all data object classes
$list = new DataObject\ClassDefinition\Listing();
$list = $list->load();

foreach ($list as $classDefinition) {
$className = DataObject::class . '\\' . ucfirst($classDefinition->getName());
$listingClass = $className . '\\Listing';

$classes[] = $className;
$classes[] = $listingClass;
}


$list = new DataObject\Objectbrick\Definition\Listing();
$list = $list->load();

foreach ($list as $brickDefinition) {
$className = 'Pimcore\\Model\\DataObject\\Objectbrick\\Data' . ucfirst($brickDefinition->getKey());

$classes[] = $className;
}

$list = new DataObject\Fieldcollection\Definition\Listing();
$list = $list->load();

foreach ($list as $fcDefinition) {
$className = 'Pimcore\\Model\\DataObject\\Fieldcollection\\Data' . ucfirst($fcDefinition->getKey());

$classes[] = $className;
}

}
}

0 comments on commit 0c5613c

Please sign in to comment.