1. Go to this page and download the library: Download okvpn/cron-bundle library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
declare(strict_types=1);
namespace App\Service;
use Okvpn\Bundle\CronBundle\Attribute\AsCron;
use Okvpn\Bundle\CronBundle\Attribute\AsPeriodicTask;
#[AsCron('*/5 * * * *', messenger: true)]
class SyncAppWorker
{
public function __invoke(array $arguments = []): void
{
// code
}
}
#[AsCron('*/10 * * * *', jitter: 60)]
class Sync2AppWorker { /* ... */ } // Run each 10 minutes with 60 sec random delay
#[AsCron('@random 3600')]
class Sync3AppWorker { /* ... */ } // Run with random 0-3600 sec
#[AsPeriodicTask('30 seconds', jitter: 5)]
class Sync4AppWorker { /* ... */ } // Run each 30 sec with 5 sec random delay.
namespace App\Cron;
use Okvpn\Bundle\CronBundle\CronSubscriberInterface;
class MyCron implements CronSubscriberInterface // implements is not {
return '*/10 * * * *';
}
}
declare(strict_types=1);
namespace Packagist\WebBundle;
use Okvpn\Bundle\CronBundle\Loader\ScheduleLoaderInterface;
use Okvpn\Bundle\CronBundle\Model\ScheduleEnvelope;
use Okvpn\Bundle\CronBundle\Model;
class DoctrineCronLoader implements ScheduleLoaderInterface
{
/**
* @inheritDoc
*/
public function getSchedules(array $options = []): iterable
{
// ... get active cron from database/etc.
yield new ScheduleEnvelope(
'yor_service_command_name', // A service name, (object must be have a __invoke method)
// !!! Important. You must mark this service with tag `okvpn.cron_service` to add into our service locator.
new Model\ScheduleStamp('*/5 * * * *'), // Cron expression
new Model\LockStamp('yor_service_command_name'), // If you want to use locking
new Model\AsyncStamp() // If you want to run asynchronously
);
yield new ScheduleEnvelope(
'app:cron:sync-amazon-orders', // Symfony console
new Model\ScheduleStamp('*/5 * * * *'), // Cron expression
new Model\LockStamp('sync-amazon-orders_1'), // If you want to use locking
new Model\ArgumentsStamp(['--integration' => 1]), // Command arguments
new Model\AsyncStamp() // If you want to run asynchronously
);
yield new ScheduleEnvelope(
'ls -l', // shell command
new Model\ScheduleStamp('*/10 * * * *'), // Cron expression
new Model\ShellStamp(['timeout'=> 300]), // Run command as shell
);
// ...
}
}
declare(strict_types=1);
namespace App\Cron;
class EntityCronLoader implements ScheduleLoaderInterface
{
public function getSchedules(array $options = []): iterable
{
if (!\in_array($group = $options['group'] ?? 'default', ['default', 'all_chunk']) && !\str_starts_with($group, 'chunk_')) {
return;
}
$chunkId = str_replace('chunk_', '', $group)
foreach ($this->registry->getAllRepos($chunkId) as $name => $repo) {
$expr = '@random ' . $this->getSyncInterval($repo);
yield new ScheduleEnvelope(
'sync:mirrors',
new Model\ScheduleStamp($expr),
new WorkerStamp(true),
new Model\ArgumentsStamp(['mirror' => $name,])
);
}
}
}
use Okvpn\Bundle\CronBundle\Event\LoopEvent;
use Okvpn\Bundle\CronBundle\Runner\TimerStorage;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
class CronStartListener
{
#[AsEventListener('loopInit')]
public function loopInit(LoopEvent $event): void
{
$dataDogS = $this->getDDog();
$event->getLoop()->addPeriodicTimer(6.0, static function () use ($dataDogS) {
$dataDogS->set('crond', getmypid());
});
}
}
use Okvpn\Bundle\CronBundle\Event\LoopEvent;
use Okvpn\Bundle\CronBundle\Runner\TimerStorage;
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
use Okvpn\Bundle\CronBundle\Runner\TimerStorage;
use React\EventLoop\Loop;
class CronStartListener
{
public function __construct(
private TimerStorage $timers,
) {
}
#[AsEventListener('loopInit')]
public function loopInit(LoopEvent $event): void
{
$redis = new RedisClient('127.0.0.1:6379');
$timers = $this->timers;
$loop = $event->getLoop();
$redis->on('message', static function (string $channel, string $payload) use ($timers, $loop) {
[$command, $args] = unserialize($payload);
if ($timers->hasTimer($envelope = $timers->find($command, $args))) {
[$timer] = $timers->getTimer($envelope);
$loop->futureTick($timer);
}
});
Loop::addPeriodicTimer(5.0, static function () use ($redis) {
$redis->ping();
});
}
}