@@ -52,7 +52,7 @@ discard block |
||
| 52 | 52 | ) { |
| 53 | 53 | $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); |
| 54 | 54 | $this->pdo = $pdo; |
| 55 | - if($this->options['use-locking'] ?? true) { |
|
| 55 | + if ($this->options['use-locking'] ?? true) { |
|
| 56 | 56 | $this->lock = $pdo->prepare('SELECT GET_LOCK(:name, 0)'); |
| 57 | 57 | $this->unlock = $pdo->prepare('SELECT RELEASE_LOCK(:name)'); |
| 58 | 58 | } |
@@ -63,7 +63,7 @@ discard block |
||
| 63 | 63 | * @return bool |
| 64 | 64 | */ |
| 65 | 65 | public function has(string $key) { |
| 66 | - if($this->hasService === null) { |
|
| 66 | + if ($this->hasService === null) { |
|
| 67 | 67 | $this->hasService = $this->pdo->prepare("SELECT COUNT(*) FROM `{$this->tableName}` WHERE service_key=:key;"); |
| 68 | 68 | } |
| 69 | 69 | $this->hasService->execute(['key' => $key]); |
@@ -76,9 +76,9 @@ discard block |
||
| 76 | 76 | * @return $this |
| 77 | 77 | */ |
| 78 | 78 | public function register(string $key) { |
| 79 | - return $this->handleException(function () use ($key) { |
|
| 80 | - if($this->services === null) { |
|
| 81 | - if($this->getServiceKeys === null) { |
|
| 79 | + return $this->handleException(function() use ($key) { |
|
| 80 | + if ($this->services === null) { |
|
| 81 | + if ($this->getServiceKeys === null) { |
|
| 82 | 82 | $this->getServiceKeys = $this->pdo->prepare("SELECT `service_key` FROM `{$this->tableName}`;"); |
| 83 | 83 | } |
| 84 | 84 | try { |
@@ -91,8 +91,8 @@ discard block |
||
| 91 | 91 | } |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | - if(!in_array($key, $this->services, true)) { |
|
| 95 | - if($this->registerRow === null) { |
|
| 94 | + if (!in_array($key, $this->services, true)) { |
|
| 95 | + if ($this->registerRow === null) { |
|
| 96 | 96 | $this->registerRow = $this->pdo->prepare("INSERT INTO `{$this->tableName}` (`service_key`) VALUES (:key)"); |
| 97 | 97 | } |
| 98 | 98 | $this->registerRow->execute(['key' => $key]); |
@@ -107,15 +107,15 @@ discard block |
||
| 107 | 107 | * @return object |
| 108 | 108 | */ |
| 109 | 109 | public function getRowByKey(string $key) { |
| 110 | - if($this->getData === null) { |
|
| 110 | + if ($this->getData === null) { |
|
| 111 | 111 | $this->getData = $this->pdo->prepare("SELECT service_key, service_last_try, service_last_run, service_next_run FROM `{$this->tableName}` WHERE service_key=:key;"); |
| 112 | 112 | } |
| 113 | 113 | try { |
| 114 | - $this->handleException(function () use ($key) { |
|
| 114 | + $this->handleException(function() use ($key) { |
|
| 115 | 115 | $this->getData->execute(['key' => $key]); |
| 116 | 116 | }); |
| 117 | 117 | $result = $this->getData->fetchObject(); |
| 118 | - if(!is_object($result)) { |
|
| 118 | + if (!is_object($result)) { |
|
| 119 | 119 | throw new RuntimeException('Row not found'); |
| 120 | 120 | } |
| 121 | 121 | return $result; |
@@ -130,10 +130,10 @@ discard block |
||
| 130 | 130 | * @return void |
| 131 | 131 | */ |
| 132 | 132 | public function setLastTryDate(string $key, DateTimeInterface $datetime): void { |
| 133 | - if($this->updateTryDate === null) { |
|
| 133 | + if ($this->updateTryDate === null) { |
|
| 134 | 134 | $this->updateTryDate = $this->pdo->prepare("INSERT INTO `{$this->tableName}` (service_key, service_last_try) VALUES (:key, :dt) ON DUPLICATE KEY UPDATE service_last_try=:dt"); |
| 135 | 135 | } |
| 136 | - $this->handleException(function () use ($key, $datetime) { |
|
| 136 | + $this->handleException(function() use ($key, $datetime) { |
|
| 137 | 137 | $this->updateTryDate->execute(['key' => $key, 'dt' => $datetime->format('Y-m-d H:i:s')]); |
| 138 | 138 | }); |
| 139 | 139 | } |
@@ -144,10 +144,10 @@ discard block |
||
| 144 | 144 | * @return void |
| 145 | 145 | */ |
| 146 | 146 | public function setLastRunDate(string $key, DateTimeInterface $datetime): void { |
| 147 | - if($this->updateRunDate === null) { |
|
| 147 | + if ($this->updateRunDate === null) { |
|
| 148 | 148 | $this->updateRunDate = $this->pdo->prepare("INSERT INTO `{$this->tableName}` (service_key, service_last_run) VALUES (:key, :dt) ON DUPLICATE KEY UPDATE service_last_run=:dt"); |
| 149 | 149 | } |
| 150 | - $this->handleException(function () use ($key, $datetime) { |
|
| 150 | + $this->handleException(function() use ($key, $datetime) { |
|
| 151 | 151 | $this->updateRunDate->execute(['key' => $key, 'dt' => $datetime->format('Y-m-d H:i:s')]); |
| 152 | 152 | }); |
| 153 | 153 | } |
@@ -158,10 +158,10 @@ discard block |
||
| 158 | 158 | * @return void |
| 159 | 159 | */ |
| 160 | 160 | public function setNextRunDate(string $key, DateTimeInterface $datetime): void { |
| 161 | - if($this->updateNextDate === null) { |
|
| 161 | + if ($this->updateNextDate === null) { |
|
| 162 | 162 | $this->updateNextDate = $this->pdo->prepare("INSERT INTO `{$this->tableName}` (service_key, service_next_run) VALUES (:key, :dt) ON DUPLICATE KEY UPDATE service_next_run=:dt"); |
| 163 | 163 | } |
| 164 | - $this->handleException(function () use ($key, $datetime) { |
|
| 164 | + $this->handleException(function() use ($key, $datetime) { |
|
| 165 | 165 | $this->updateNextDate->execute(['key' => $key, 'dt' => $datetime->format('Y-m-d H:i:s')]); |
| 166 | 166 | }); |
| 167 | 167 | } |
@@ -175,7 +175,7 @@ discard block |
||
| 175 | 175 | $now ??= new DateTimeImmutable(); |
| 176 | 176 | $data = (object) ['count' => 0]; |
| 177 | 177 | $services = $this->fetchServices($now); |
| 178 | - foreach($services as $service) { |
|
| 178 | + foreach ($services as $service) { |
|
| 179 | 179 | try { |
| 180 | 180 | $this->lock($service->key); |
| 181 | 181 | $fn($service); |
@@ -192,16 +192,16 @@ discard block |
||
| 192 | 192 | * @return Service[] |
| 193 | 193 | */ |
| 194 | 194 | private function fetchServices(DateTimeInterface $now): array { |
| 195 | - if($this->selectOverdueServices === null) { |
|
| 195 | + if ($this->selectOverdueServices === null) { |
|
| 196 | 196 | $this->selectOverdueServices = $this->pdo->prepare("SELECT service_key, service_last_try, service_last_run, service_next_run FROM `{$this->tableName}` WHERE IFNULL(service_next_run, DATE('2000-01-01')) <= :dt ORDER BY service_last_try;"); |
| 197 | 197 | } |
| 198 | - return $this->handleException(function () use ($now) { |
|
| 198 | + return $this->handleException(function() use ($now) { |
|
| 199 | 199 | $this->selectOverdueServices->execute(['dt' => $now->format('Y-m-d H:i:d')]); |
| 200 | 200 | try { |
| 201 | 201 | /** @var list<array{service_key: string}> $services */ |
| 202 | 202 | $services = $this->selectOverdueServices->fetchAll(PDO::FETCH_ASSOC); |
| 203 | 203 | $result = []; |
| 204 | - foreach($services as $service) { |
|
| 204 | + foreach ($services as $service) { |
|
| 205 | 205 | $result[] = new Service($service['service_key']); |
| 206 | 206 | } |
| 207 | 207 | return $result; |
@@ -221,7 +221,7 @@ discard block |
||
| 221 | 221 | $lockName = sprintf('%s%s', $this->options['lock-prefix'] ?? '', $key); |
| 222 | 222 | $this->lock->execute(['name' => $lockName]); |
| 223 | 223 | $lockObtained = $this->lock->fetchColumn(0); |
| 224 | - if(!$lockObtained) { |
|
| 224 | + if (!$lockObtained) { |
|
| 225 | 225 | throw new RuntimeException(sprintf('Could not obtain lock "%s"', $lockName)); |
| 226 | 226 | } |
| 227 | 227 | } finally { |
@@ -245,13 +245,13 @@ discard block |
||
| 245 | 245 | try { |
| 246 | 246 | return $fn(); |
| 247 | 247 | } catch (PDOException $e) { |
| 248 | - if($e->getCode() === self::MYSQL_ERR_TABLE_MSSING) { |
|
| 248 | + if ($e->getCode() === self::MYSQL_ERR_TABLE_MSSING) { |
|
| 249 | 249 | // Field is missing, let's have a look what is going on... |
| 250 | 250 | $this->pdo->exec("CREATE TABLE IF NOT EXISTS `{$this->tableName}` (`service_key` VARCHAR(255) NOT NULL DEFAULT '', `service_last_try` DATETIME NULL DEFAULT NULL, `service_last_run` DATETIME NULL DEFAULT NULL, `service_next_run` DATETIME NULL DEFAULT NULL, PRIMARY KEY (`service_key`));"); |
| 251 | 251 | return $this->retry($fn); |
| 252 | 252 | } |
| 253 | 253 | |
| 254 | - if($e->getCode() === self::MYSQL_ERR_TABLE_COLUMN_MSSING) { |
|
| 254 | + if ($e->getCode() === self::MYSQL_ERR_TABLE_COLUMN_MSSING) { |
|
| 255 | 255 | // Field is missing, let's have a look what is going on... |
| 256 | 256 | $this->checkIfOldTableVersion(); |
| 257 | 257 | return $this->retry($fn); |
@@ -271,19 +271,19 @@ discard block |
||
| 271 | 271 | |
| 272 | 272 | private function checkIfOldTableVersion(): void { |
| 273 | 273 | $stmt = $this->pdo->query("SHOW COLUMNS FROM `{$this->tableName}` LIKE 'service_next_run';"); |
| 274 | - if($stmt === false) { |
|
| 274 | + if ($stmt === false) { |
|
| 275 | 275 | throw new RuntimeException('Could not check if service_next_run field exists'); |
| 276 | 276 | } |
| 277 | 277 | $serviceNextRunField = $stmt->fetchAll(PDO::FETCH_ASSOC); |
| 278 | 278 | |
| 279 | - if(!count($serviceNextRunField)) { |
|
| 279 | + if (!count($serviceNextRunField)) { |
|
| 280 | 280 | $this->pdo->exec("ALTER TABLE `{$this->tableName}` ADD COLUMN `service_next_run` DATETIME NULL DEFAULT NULL AFTER `service_last_run`;"); |
| 281 | 281 | $stmt = $this->pdo->query("SHOW COLUMNS FROM `{$this->tableName}` LIKE 'service_timeout';"); |
| 282 | - if($stmt === false) { |
|
| 282 | + if ($stmt === false) { |
|
| 283 | 283 | throw new RuntimeException('Could not check if service_timeout field exists'); |
| 284 | 284 | } |
| 285 | 285 | $serviceTimeoutField = $stmt->fetchAll(PDO::FETCH_ASSOC); |
| 286 | - if(count($serviceTimeoutField)) { |
|
| 286 | + if (count($serviceTimeoutField)) { |
|
| 287 | 287 | $this->pdo->exec("UPDATE `{$this->tableName}` SET service_next_run = DATE_ADD(service_last_run, INTERVAL service_timeout SECOND)"); |
| 288 | 288 | $this->pdo->exec("ALTER TABLE `{$this->tableName}` DROP COLUMN `service_timeout`;"); |
| 289 | 289 | } |
@@ -75,7 +75,7 @@ discard block |
||
| 75 | 75 | try { |
| 76 | 76 | $this->getData->execute(['key' => $key]); |
| 77 | 77 | $result = $this->getData->fetchObject(); |
| 78 | - if(!is_object($result)) { |
|
| 78 | + if (!is_object($result)) { |
|
| 79 | 79 | throw new RuntimeException('Row not found'); |
| 80 | 80 | } |
| 81 | 81 | return $result; |
@@ -92,7 +92,7 @@ discard block |
||
| 92 | 92 | public function lockAndIterateServices(DateTimeInterface $now, callable $fn): int { |
| 93 | 93 | $count = 0; |
| 94 | 94 | $services = $this->fetchServices($now); |
| 95 | - foreach($services as $service) { |
|
| 95 | + foreach ($services as $service) { |
|
| 96 | 96 | $fn($service); |
| 97 | 97 | } |
| 98 | 98 | return $count; |
@@ -107,7 +107,7 @@ discard block |
||
| 107 | 107 | try { |
| 108 | 108 | /** @var iterable<array{service_key: string}> $services */ |
| 109 | 109 | $services = $this->selectServices->fetchAll(PDO::FETCH_ASSOC); |
| 110 | - foreach($services as $service) { |
|
| 110 | + foreach ($services as $service) { |
|
| 111 | 111 | yield new Service(key: $service['service_key']); |
| 112 | 112 | } |
| 113 | 113 | } finally { |
@@ -122,11 +122,11 @@ discard block |
||
| 122 | 122 | private function migrate(int $version, string $statement): void { |
| 123 | 123 | /** @var PDOStatement|false $stmt */ |
| 124 | 124 | $stmt = $this->pdo->query('PRAGMA user_version'); |
| 125 | - if($stmt === false) { |
|
| 125 | + if ($stmt === false) { |
|
| 126 | 126 | throw new RuntimeException('Failed to get user_version'); |
| 127 | 127 | } |
| 128 | 128 | $currentVersion = (int) $stmt->fetchColumn(0); |
| 129 | - if($currentVersion < $version) { |
|
| 129 | + if ($currentVersion < $version) { |
|
| 130 | 130 | $this->pdo->exec($statement); |
| 131 | 131 | $this->pdo->exec("PRAGMA user_version={$version}"); |
| 132 | 132 | } |
@@ -55,7 +55,7 @@ discard block |
||
| 55 | 55 | * @return $this |
| 56 | 56 | */ |
| 57 | 57 | public function on(string $event, callable $fn) { |
| 58 | - if(!array_key_exists($event, $this->listeners)) { |
|
| 58 | + if (!array_key_exists($event, $this->listeners)) { |
|
| 59 | 59 | $this->listeners[$event] = []; |
| 60 | 60 | } |
| 61 | 61 | $this->listeners[$event][] = $fn; |
@@ -69,8 +69,8 @@ discard block |
||
| 69 | 69 | public function run(?DateTimeInterface $now = null): int { |
| 70 | 70 | /** @var DateTimeInterface $dt */ |
| 71 | 71 | $dt = $now ?? new DateTimeImmutable(); |
| 72 | - return $this->attributeRepository->lockAndIterateServices($dt, function (Service $service) { |
|
| 73 | - if(!array_key_exists($service->key, $this->services)) { |
|
| 72 | + return $this->attributeRepository->lockAndIterateServices($dt, function(Service $service) { |
|
| 73 | + if (!array_key_exists($service->key, $this->services)) { |
|
| 74 | 74 | return; |
| 75 | 75 | } |
| 76 | 76 | $eventParams = ['serviceName' => $service->key]; |
@@ -78,7 +78,7 @@ discard block |
||
| 78 | 78 | $this->fireEvent('service-start', $eventParams); |
| 79 | 79 | $serviceData = $this->services[$service->key]; |
| 80 | 80 | $this->attributeRepository->setLastTryDate($service->key, new DateTimeImmutable()); |
| 81 | - if($this->methodInvoker !== null) { |
|
| 81 | + if ($this->methodInvoker !== null) { |
|
| 82 | 82 | $result = $this->methodInvoker->invoke($serviceData->fn, $eventParams); |
| 83 | 83 | } else { |
| 84 | 84 | $result = call_user_func($serviceData->fn, $service); |
@@ -86,13 +86,13 @@ discard block |
||
| 86 | 86 | $this->attributeRepository->setLastRunDate($service->key, new DateTimeImmutable()); |
| 87 | 87 | $nextRunDate = IntervalParser::getNext($serviceData->interval); |
| 88 | 88 | $this->attributeRepository->setNextRunDate($serviceData->key, $nextRunDate); |
| 89 | - if($result !== false) { |
|
| 89 | + if ($result !== false) { |
|
| 90 | 90 | $this->fireEvent('service-success', $eventParams); |
| 91 | 91 | } |
| 92 | 92 | } catch (Throwable $e) { |
| 93 | 93 | $eventParams['exception'] = $e; |
| 94 | 94 | $this->fireEvent('service-failure', $eventParams); |
| 95 | - if($this->logger !== null) { |
|
| 95 | + if ($this->logger !== null) { |
|
| 96 | 96 | $this->logger->critical("{$service}: {$e->getMessage()}", ['exception' => $e]); |
| 97 | 97 | } else { |
| 98 | 98 | throw new RuntimeException("{$service}: {$e->getMessage()}", (int) $e->getCode(), $e); |
@@ -106,10 +106,10 @@ discard block |
||
| 106 | 106 | * @param array<string, mixed> $params |
| 107 | 107 | */ |
| 108 | 108 | private function fireEvent(string $event, array $params): void { |
| 109 | - if(array_key_exists($event, $this->listeners)) { |
|
| 109 | + if (array_key_exists($event, $this->listeners)) { |
|
| 110 | 110 | try { |
| 111 | - foreach($this->listeners[$event] as $listener) { |
|
| 112 | - if($this->methodInvoker !== null) { |
|
| 111 | + foreach ($this->listeners[$event] as $listener) { |
|
| 112 | + if ($this->methodInvoker !== null) { |
|
| 113 | 113 | $this->methodInvoker->invoke($listener, $params); |
| 114 | 114 | } else { |
| 115 | 115 | call_user_func($listener, $params['serviceName'] ?? null); |
@@ -16,7 +16,7 @@ discard block |
||
| 16 | 16 | */ |
| 17 | 17 | public static function create($init = null): DateTime {
|
| 18 | 18 | try {
|
| 19 | - if($init instanceof DateTimeInterface) {
|
|
| 19 | + if ($init instanceof DateTimeInterface) {
|
|
| 20 | 20 | return new DateTime($init->format('c'));
|
| 21 | 21 | } |
| 22 | 22 | return new DateTime($init ?? 'now'); |
@@ -31,10 +31,10 @@ discard block |
||
| 31 | 31 | */ |
| 32 | 32 | public static function createImmutable($init = null): DateTimeImmutable {
|
| 33 | 33 | try {
|
| 34 | - if($init instanceof DateTimeImmutable) {
|
|
| 34 | + if ($init instanceof DateTimeImmutable) {
|
|
| 35 | 35 | return $init; |
| 36 | 36 | } |
| 37 | - if($init instanceof DateTimeInterface) {
|
|
| 37 | + if ($init instanceof DateTimeInterface) {
|
|
| 38 | 38 | return new DateTimeImmutable($init->format('c'));
|
| 39 | 39 | } |
| 40 | 40 | return new DateTimeImmutable($init ?? 'now'); |
@@ -17,20 +17,20 @@ discard block |
||
| 17 | 17 | * @return DateTimeImmutable |
| 18 | 18 | */ |
| 19 | 19 | public static function getNext($interval, ?DateTimeInterface $now = null): DateTimeImmutable { |
| 20 | - if($now === null) { |
|
| 20 | + if ($now === null) { |
|
| 21 | 21 | $now = new DateTimeImmutable(); |
| 22 | 22 | } else { |
| 23 | 23 | $now = DateTimeHelper::createImmutable($now); |
| 24 | 24 | } |
| 25 | 25 | $result = null; |
| 26 | - foreach(self::parse($interval, $now) as $date) { |
|
| 27 | - if($result === null) { |
|
| 26 | + foreach (self::parse($interval, $now) as $date) { |
|
| 27 | + if ($result === null) { |
|
| 28 | 28 | $result = $date; |
| 29 | - } elseif($date < $result) { |
|
| 29 | + } elseif ($date < $result) { |
|
| 30 | 30 | $result = $date; |
| 31 | 31 | } |
| 32 | 32 | } |
| 33 | - if($result === null) { |
|
| 33 | + if ($result === null) { |
|
| 34 | 34 | throw new RuntimeException('No alternative lays in the future'); |
| 35 | 35 | } |
| 36 | 36 | return $result; |
@@ -42,12 +42,12 @@ discard block |
||
| 42 | 42 | * @return Generator<DateTimeImmutable> |
| 43 | 43 | */ |
| 44 | 44 | private static function parse($interval, DateTimeImmutable $now): Generator { |
| 45 | - if(is_array($interval)) { |
|
| 46 | - foreach($interval as $inner) { |
|
| 45 | + if (is_array($interval)) { |
|
| 46 | + foreach ($interval as $inner) { |
|
| 47 | 47 | /** @var TInterval $inner */ |
| 48 | 48 | yield from self::parse($inner, $now); |
| 49 | 49 | } |
| 50 | - } elseif(preg_match('{^\\d+$}', (string) $interval)) { |
|
| 50 | + } elseif (preg_match('{^\\d+$}', (string) $interval)) { |
|
| 51 | 51 | yield self::parseInt((int) $interval, $now); |
| 52 | 52 | } else { |
| 53 | 53 | yield self::parseString((string) $interval, $now); |
@@ -69,7 +69,7 @@ discard block |
||
| 69 | 69 | * @return DateTimeImmutable |
| 70 | 70 | */ |
| 71 | 71 | private static function parseString(string $interval, DateTimeImmutable $now): DateTimeImmutable { |
| 72 | - if(preg_match('/^(\\d{1,2}|\\*):(\\d{1,2}|\\*)(?::(\\d{1,2}|\\*))?$/', $interval, $matches)) { |
|
| 72 | + if (preg_match('/^(\\d{1,2}|\\*):(\\d{1,2}|\\*)(?::(\\d{1,2}|\\*))?$/', $interval, $matches)) { |
|
| 73 | 73 | $matches[] = 0; |
| 74 | 74 | [$hours, $minutes, $seconds] = array_slice($matches, 1); |
| 75 | 75 | $today = DateTimeHelper::createImmutable($now)->setTime((int) $hours, (int) $minutes, (int) $seconds); |
@@ -90,15 +90,15 @@ discard block |
||
| 90 | 90 | */ |
| 91 | 91 | private static function nearst(array $possibleDates, DateTimeImmutable $now) { |
| 92 | 92 | $current = null; |
| 93 | - foreach($possibleDates as $possibleDate) { |
|
| 94 | - if($now > $possibleDate) { // The current date is in the past |
|
| 93 | + foreach ($possibleDates as $possibleDate) { |
|
| 94 | + if ($now > $possibleDate) { // The current date is in the past |
|
| 95 | 95 | continue; |
| 96 | 96 | } |
| 97 | - if($current === null || $possibleDate < $current) { |
|
| 97 | + if ($current === null || $possibleDate < $current) { |
|
| 98 | 98 | $current = $possibleDate; |
| 99 | 99 | } |
| 100 | 100 | } |
| 101 | - if($current !== null) { |
|
| 101 | + if ($current !== null) { |
|
| 102 | 102 | return $current; |
| 103 | 103 | } |
| 104 | 104 | throw new RuntimeException('No alternative lays in the future'); |