From 333a7b33f21f6300f33b8481733a777da8e90fa9 Mon Sep 17 00:00:00 2001 From: Thomas Zilio Date: Tue, 11 Aug 2020 09:38:20 +0200 Subject: [PATCH] Introduzione sistema di cron per la gestione di task ricorrenti --- composer.json | 8 ++-- cron.php | 88 +++++++++++++++++++++++++++++++++++++ src/Tasks/Manager.php | 15 +++++++ src/Tasks/Task.php | 39 ++++++++++++++++ src/Tasks/TaskInterface.php | 11 +++++ update/2_4_18.sql | 12 +++++ 6 files changed, 168 insertions(+), 5 deletions(-) create mode 100644 cron.php create mode 100644 src/Tasks/Manager.php create mode 100644 src/Tasks/Task.php create mode 100644 src/Tasks/TaskInterface.php create mode 100644 update/2_4_18.sql diff --git a/composer.json b/composer.json index 8b51491fc..145f60731 100755 --- a/composer.json +++ b/composer.json @@ -24,6 +24,7 @@ "php": ">=5.6", "ext-curl": "*", "ext-dom": "*", + "ext-fileinfo": "*", "ext-intl": "*", "ext-json": "*", "ext-libxml": "*", @@ -33,10 +34,10 @@ "ext-simplexml": "*", "ext-xsl": "*", "ext-zip": "*", - "ext-fileinfo": "*", "aluguest/ical-easy-reader": "^1.5", "danielstjules/stringy": "^3.1", "davidepastore/codice-fiscale": "^0.4.0", + "dragonmantank/cron-expression": "^3.0", "ezyang/htmlpurifier": "^4.8", "filp/whoops": "^2.1", "guzzlehttp/guzzle": "^6.3", @@ -82,9 +83,6 @@ "sort-packages": true, "optimize-autoloader": true, "apcu-autoloader": true, - "prefer-stable": true, - "platform": { - "php": "5.6.4" - } + "prefer-stable": true } } diff --git a/cron.php b/cron.php new file mode 100644 index 000000000..2667d212a --- /dev/null +++ b/cron.php @@ -0,0 +1,88 @@ +/cron.php" + +use Carbon\Carbon; +use Models\Cache; +use Monolog\Handler\RotatingFileHandler; +use Monolog\Logger; +use Tasks\CronExpression; +use Tasks\Task; + +// Rimozione delle limitazioni sull'esecuzione +//set_time_limit(0); +//ignore_user_abort(true); + +// Chiusura della richiesta alla pagina +//flush(); + +$skip_permissions = true; +include_once __DIR__.'/core.php'; + +// Disabilita della sessione +session_write_close(); + +// Aggiunta di un logger specifico +$logger = new Logger('Tasks'); +$handler = new RotatingFileHandler(DOCROOT.'/logs/cron_Test.log', 0); +$handler->setFormatter($monologFormatter); +$logger->pushHandler($handler); + +// Lettura della cache +$ultima_esecuzione = Cache::get('Ultima esecuzione del cron'); +$data = $ultima_esecuzione->content; + +// Impostazioni sugli slot di esecuzione +$slot_duration = 5; + +// Controllo sull'ultima esecuzione +$data = $data ? new Carbon($data) : null; +$minimo_esecuzione = (new Carbon())->addMinutes($slot_duration * 5); +if (!empty($data) && $data->greaterThanOrEqualTo($minimo_esecuzione)) { + return; +} + +// Calcolo del primo slot disponibile +$adesso = new Carbon(); +$slot = (new Carbon())->startOfHour(); +while ($adesso->greaterThanOrEqualTo($slot)) { + $slot->addMinutes($slot_duration); +} + +// Esecuzione ricorrente +$number = 1; +while (true) { + // Risveglio programmato tramite slot + $timestamp = $slot->getTimestamp(); + time_sleep_until($timestamp); + + // Registrazione nei log + $logger->info('Cron #'.$number.' (slot timestamp: '.$timestamp.')'); + + // Aggiornamento dei cron disponibili + $tasks = Task::all(); + foreach ($tasks as $task) { + $cron = CronExpression::factory($task->expression); + + // Esecuzione diretta solo nel caso in cui sia prevista + if ($cron->isDue()) { + $task->execute(); + } + } + + // Registrazione dell'esecuzione + $adesso = new Carbon(); + $ultima_esecuzione->set($adesso->__toString()); + + // Individuazione dello slot di 5 minuti per l'esecuzione successiva + while ($adesso->greaterThanOrEqualTo($slot)) { + $slot->addMinutes($slot_duration); + } + ++$number; +} diff --git a/src/Tasks/Manager.php b/src/Tasks/Manager.php new file mode 100644 index 000000000..b85a77da9 --- /dev/null +++ b/src/Tasks/Manager.php @@ -0,0 +1,15 @@ +task = $task; + } + + abstract public function execute(); +} diff --git a/src/Tasks/Task.php b/src/Tasks/Task.php new file mode 100644 index 000000000..2fc3140f6 --- /dev/null +++ b/src/Tasks/Task.php @@ -0,0 +1,39 @@ +attributes['class']; + $manager = new $class($this); + + // Esecuzione + $result = $manager->execute(); + + // Salvtagggio dell'esecuzione + $this->last_executed_at = new Carbon(); + $this->save(); + + return $result; + } + + public function delete() + { + return false; + } +} diff --git a/src/Tasks/TaskInterface.php b/src/Tasks/TaskInterface.php new file mode 100644 index 000000000..516c9b030 --- /dev/null +++ b/src/Tasks/TaskInterface.php @@ -0,0 +1,11 @@ +