Skip to content

Commit

Permalink
[Maintenance] refactor maintenance (#3895)
Browse files Browse the repository at this point in the history
* [Maintenance] deprecate old maintenance job and introduce new tagged services for identifiers. also extract all current core maintenance tasks into seperate maintenance files and remove Business Logic from models

* deprecate the SystemEvents::MAINTENANCE Event
implement EcommerceFramework Tasks with the new tag
add docs for maintenance tasks

* fix link to maintenance_tasks docs

* [Maintenance] fix Version Cleanup Task

* add missing CheckErrorLogDb Maintenance Task
  • Loading branch information
dpfaffenbauer authored and weisswurstkanone committed Apr 29, 2019
1 parent 862f0b0 commit 2f3315f
Show file tree
Hide file tree
Showing 50 changed files with 1,861 additions and 445 deletions.
80 changes: 50 additions & 30 deletions bundles/CoreBundle/Command/MaintenanceCommand.php
Expand Up @@ -17,20 +17,39 @@
use Pimcore\Console\AbstractCommand;
use Pimcore\Event\System\MaintenanceEvent;
use Pimcore\Event\SystemEvents;
use Pimcore\Logger;
use Pimcore\Maintenance\CallableTask;
use Pimcore\Maintenance\ExecutorInterface;
use Pimcore\Model\Schedule;
use Pimcore\Model\Schedule\Maintenance\Job;
use Psr\Log\LoggerInterface;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;

class MaintenanceCommand extends AbstractCommand
{
protected $systemTasks = [
'scheduledtasks', 'cleanupcache', 'logmaintenance', 'sanitycheck', 'cleanuplogfiles', 'versioncleanup',
'versioncompress', 'redirectcleanup', 'cleanupbrokenviews', 'downloadmaxminddb',
'tmpstorecleanup', 'imageoptimize'
];
/**
* @var ExecutorInterface
*/
private $maintenanceExecutor;

/**
* @var LoggerInterface
*/
private $logger;

/**
* @param ExecutorInterface $maintenanceExecutor
* @param LoggerInterface $logger
*/
public function __construct(ExecutorInterface $maintenanceExecutor, LoggerInterface $logger)
{
$this->maintenanceExecutor = $maintenanceExecutor;
$this->logger = $logger;

parent::__construct();
}


protected function configure()
{
Expand All @@ -39,8 +58,8 @@ protected function configure()
$help = $description . '. Valid jobs are: ' . "\n\n";
$help .= ' <comment>*</comment> any bundle class name handling maintenance (e.g. <comment>PimcoreEcommerceFrameworkBundle</comment>)' . "\n";

foreach ($this->systemTasks as $systemTask) {
$help .= ' <comment>*</comment> ' . $systemTask . "\n";
foreach ($this->maintenanceExecutor->getTaskNames() as $taskName) {
$help .= ' <comment>*</comment> ' . $taskName . "\n";
}

$this
Expand Down Expand Up @@ -82,32 +101,33 @@ protected function execute(InputInterface $input, OutputInterface $output)
$manager->setExcludedJobs($excludedJobs);
$manager->setForce((bool) $input->getOption('force'));

// register scheduled tasks
$manager->registerJob(Job::fromMethodCall('scheduledtasks', new Schedule\Task\Executor(), 'execute'));
$manager->registerJob(Job::fromMethodCall('logmaintenance', new \Pimcore\Log\Maintenance(), 'mail'));
$manager->registerJob(Job::fromMethodCall('cleanuplogfiles', new \Pimcore\Log\Maintenance(), 'cleanupLogFiles'));
$manager->registerJob(Job::fromMethodCall('httperrorlog', new \Pimcore\Log\Maintenance(), 'httpErrorLogCleanup'));
$manager->registerJob(Job::fromMethodCall('checkErrorLogsDb', new \Pimcore\Log\Maintenance(), 'checkErrorLogsDb'));
$manager->registerJob(Job::fromMethodCall('archiveLogEntries', new \Pimcore\Log\Maintenance(), 'archiveLogEntries'));
$manager->registerJob(Job::fromMethodCall('sanitycheck', '\\Pimcore\\Model\\Element\\Service', 'runSanityCheck'));
$manager->registerJob(Job::fromMethodCall('versioncleanup', new \Pimcore\Model\Version(), 'maintenanceCleanUp'));
$manager->registerJob(Job::fromMethodCall('versioncompress', new \Pimcore\Model\Version(), 'maintenanceCompress'));
$manager->registerJob(Job::fromMethodCall('redirectcleanup', '\\Pimcore\\Model\\Redirect', 'maintenanceCleanUp'));
$manager->registerJob(Job::fromMethodCall('cleanupbrokenviews', '\\Pimcore\\Db', 'cleanupBrokenViews'));
$manager->registerJob(Job::fromMethodCall('downloadmaxminddb', '\\Pimcore\\Update', 'updateMaxmindDb'));
$manager->registerJob(Job::fromMethodCall('cleanupcache', '\\Pimcore\\Cache', 'maintenance'));
$manager->registerJob(Job::fromMethodCall('tmpstorecleanup', '\\Pimcore\\Model\\Tool\\TmpStore', 'cleanup'));
$manager->registerJob(Job::fromMethodCall('imageoptimize', '\\Pimcore\\Model\\Asset\\Image\\Thumbnail\\Processor', 'processOptimizeQueue'));
$manager->registerJob(Job::fromMethodCall('cleanupTmpFiles', '\\Pimcore\\Tool\\Housekeeping', 'cleanupTmpFiles'));
$manager->registerJob(Job::fromMethodCall('cleanupSymfonyProfilingData', '\\Pimcore\\Tool\\Housekeeping', 'cleanupSymfonyProfilingData'));
$manager->registerJob(Job::fromMethodCall('markexpiredtagsdisabled', '\\Pimcore\\Model\\Tool\\Tag\\Config', 'markExpiredTagsAsDisabled'));

$event = new MaintenanceEvent($manager);
\Pimcore::getEventDispatcher()->dispatch(SystemEvents::MAINTENANCE, $event);

$manager->run();
foreach ($manager->getJobs() as $job) {
@trigger_error(
sprintf('Job with ID %s is registered using the deprecated %s Event, please use a service tag instead', $job->getId(), SystemEvents::MAINTENANCE),
E_USER_DEPRECATED
);

$trackerReflector = new \ReflectionClass(Job::class);
$callableProperty = $trackerReflector->getProperty('callable');
$callableProperty->setAccessible(true);

$argumentsProperty = $trackerReflector->getProperty('arguments');
$argumentsProperty->setAccessible(true);

$callable = $callableProperty->getValue($job);
$arguments = $argumentsProperty->getValue($job);

if (is_callable($callable)) {
$this->maintenanceExecutor->registerTask($job->getId(), CallableTask::fromCallable($callable, $arguments ?? []));
}
}

$this->maintenanceExecutor->executeMaintenance($validJobs, $excludedJobs, (bool) $input->getOption('force'));

Logger::info('All maintenance-jobs finished!');
$this->logger->info('All maintenance-jobs finished!');
}

/**
Expand Down
@@ -0,0 +1,43 @@
<?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\Bundle\CoreBundle\DependencyInjection\Compiler;

use Pimcore\Maintenance\Executor;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;

class RegisterMaintenanceTaskPass implements CompilerPassInterface
{
/**
* {@inheritdoc}
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition(Executor::class)) {
return;
}

$definition = $container->getDefinition(Executor::class);

foreach ($container->findTaggedServiceIds('pimcore.maintenance.task') as $id => $tags) {
if (!isset($tags[0]['type'])) {
throw new \InvalidArgumentException('Tagged Maintenance Task `'.$id.'` needs to a `type` attribute.');
}

$definition->addMethodCall('registerTask', [$tags[0]['type'], new Reference($id)]);
}
}
}
Expand Up @@ -106,6 +106,7 @@ public function loadInternal(array $config, ContainerBuilder $container)
$loader->load('sitemaps.yml');
$loader->load('aliases.yml');
$loader->load('image_optimizers.yml');
$loader->load('maintenance.yml');
$loader->load('commands.yml');

$this->configureImplementationLoaders($container, $config);
Expand Down Expand Up @@ -336,6 +337,7 @@ private function configureTargeting(ContainerBuilder $container, LoaderInterface

if ($config['enabled']) {
// enable targeting by registering listeners
$loader->load('targeting/services.yml');
$loader->load('targeting/listeners.yml');

// add session support by registering the session configurator and session storage
Expand Down
2 changes: 2 additions & 0 deletions bundles/CoreBundle/PimcoreCoreBundle.php
Expand Up @@ -26,6 +26,7 @@
use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\PimcoreContextResolverAwarePass;
use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\PimcoreGlobalTemplatingVariablesPass;
use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\RegisterImageOptimizersPass;
use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\RegisterMaintenanceTaskPass;
use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\ServiceControllersPass;
use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\SessionConfiguratorPass;
use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\TargetingOverrideHandlersPass;
Expand Down Expand Up @@ -84,5 +85,6 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new LongRunningHelperPass());
$container->addCompilerPass(new WorkflowPass());
$container->addCompilerPass(new RegisterImageOptimizersPass());
$container->addCompilerPass(new RegisterMaintenanceTaskPass());
}
}
9 changes: 8 additions & 1 deletion bundles/CoreBundle/Resources/config/commands.yml
Expand Up @@ -3,4 +3,11 @@ services:
arguments:
- '@Pimcore\Image\Optimizer'
tags:
- { name: console.command, command: 'pimcore:thumbnails:optimize-images' }
- { name: console.command, command: 'pimcore:thumbnails:optimize-images' }

Pimcore\Bundle\CoreBundle\Command\MaintenanceCommand:
arguments:
- '@Pimcore\Maintenance\Executor'
- '@logger'
tags:
- { name: console.command, command: 'pimcore:maintenance' }
109 changes: 109 additions & 0 deletions bundles/CoreBundle/Resources/config/maintenance.yml
@@ -0,0 +1,109 @@
services:
_defaults:
autowire: true
autoconfigure: true

Pimcore\Maintenance\Executor:
arguments:
- 'maintenance.pid'
- '@logger'

Pimcore\Maintenance\Tasks\ScheduledTasksTask:
arguments:
- '@logger'
tags:
- { name: pimcore.maintenance.task, type: scheduledtasks }

Pimcore\Maintenance\Tasks\LogMailMaintenanceTask:
arguments:
- '@doctrine.dbal.default_connection'
tags:
- { name: pimcore.maintenance.task, type: logmaintenance }

Pimcore\Maintenance\Tasks\LogCleanupTask:
tags:
- { name: pimcore.maintenance.task, type: cleanuplogfiles }

Pimcore\Maintenance\Tasks\LogErrorCleanupTask:
arguments:
- '@doctrine.dbal.default_connection'
tags:
- { name: pimcore.maintenance.task, type: httperrorlog }

Pimcore\Maintenance\Tasks\LogArchiveTask:
arguments:
- '@doctrine.dbal.default_connection'
tags:
- { name: pimcore.maintenance.task, type: archiveLogEntries }

Pimcore\Maintenance\Tasks\SanitizeElementsTask:
arguments:
- '@logger'
tags:
- { name: pimcore.maintenance.task, type: runSanityCheck }

Pimcore\Maintenance\Tasks\VersionsCleanupTask:
arguments:
- '@logger'
tags:
- { name: pimcore.maintenance.task, type: versioncleanup }

Pimcore\Maintenance\Tasks\VersionsCompressTask:
arguments:
- '@logger'
tags:
- { name: pimcore.maintenance.task, type: versioncompress }

Pimcore\Maintenance\Tasks\RedirectCleanupTask:
arguments:
- '@logger'
tags:
- { name: pimcore.maintenance.task, type: redirectcleanup }

Pimcore\Maintenance\Tasks\DbCleanupBrokenViewsTask:
arguments:
- '@doctrine.dbal.default_connection'
- '@logger'
tags:
- { name: pimcore.maintenance.task, type: cleanupbrokenviews }

Pimcore\Maintenance\Tasks\DownloadMaxMinDbTask:
arguments:
- '@logger'
tags:
- { name: pimcore.maintenance.task, type: downloadmaxminddb }

Pimcore\Maintenance\Tasks\CacheCleanupTask:
arguments:
- '@Pimcore\Cache\Core\CoreHandlerInterface'
tags:
- { name: pimcore.maintenance.task, type: cleanupcache }

Pimcore\Maintenance\Tasks\TmpStoreCleanupTask:
arguments:
- '@doctrine.dbal.default_connection'
tags:
- { name: pimcore.maintenance.task, type: tmpstorecleanup }

Pimcore\Maintenance\Tasks\ImageOptimizeTask:
arguments:
- '@Pimcore\Image\Optimizer'
- '@logger'
tags:
- { name: pimcore.maintenance.task, type: imageoptimize }

Pimcore\Maintenance\Tasks\HousekeepingTask:
tags:
- { name: pimcore.maintenance.task, type: housekeeping }

Pimcore\Maintenance\Tasks\TagsExpireTask:
arguments:
- '@logger'
tags:
- { name: pimcore.maintenance.task, type: markexpiredtagsdisabled }

Pimcore\Maintenance\Tasks\CheckErrorLogsDbTask:
arguments:
- '@doctrine.dbal.default_connection'
tags:
- { name: pimcore.maintenance.task, type: checkerrorlogsdb }
Expand Up @@ -9,5 +9,4 @@ services:
Pimcore\Targeting\EventListener\DocumentTargetGroupListener: ~
Pimcore\Targeting\EventListener\FullPageCacheCookieCleanupListener: ~
Pimcore\Targeting\EventListener\VisitedPagesCountListener: ~
Pimcore\Targeting\EventListener\MaintenanceListener: ~
Pimcore\Targeting\EventListener\ToolbarListener: ~
7 changes: 7 additions & 0 deletions bundles/CoreBundle/Resources/config/targeting/services.yml
@@ -0,0 +1,7 @@
services:
_defaults:
autowire: true
autoconfigure: true
public: false

Pimcore\Targeting\Maintenance\TargetingStorageTask: ~
Expand Up @@ -82,6 +82,7 @@ protected function loadInternal(array $config, ContainerBuilder $container)
$loader->load('voucher_service.yml');
$loader->load('offer_tool.yml');
$loader->load('tracking_manager.yml');
$loader->load('maintenance.yml');

$this->registerFactoryConfiguration($container, $config['factory']);
$this->registerEnvironmentConfiguration($container, $config['environment']);
Expand Down

0 comments on commit 2f3315f

Please sign in to comment.