1ce74398dSGreg Roach<?php 23976b470SGreg Roach 3ce74398dSGreg Roach/** 4ce74398dSGreg Roach * webtrees: online genealogy 5d11be702SGreg Roach * Copyright (C) 2023 webtrees development team 6ce74398dSGreg Roach * This program is free software: you can redistribute it and/or modify 7ce74398dSGreg Roach * it under the terms of the GNU General Public License as published by 8ce74398dSGreg Roach * the Free Software Foundation, either version 3 of the License, or 9ce74398dSGreg Roach * (at your option) any later version. 10ce74398dSGreg Roach * This program is distributed in the hope that it will be useful, 11ce74398dSGreg Roach * but WITHOUT ANY WARRANTY; without even the implied warranty of 12ce74398dSGreg Roach * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13ce74398dSGreg Roach * GNU General Public License for more details. 14ce74398dSGreg Roach * You should have received a copy of the GNU General Public License 1589f7189bSGreg Roach * along with this program. If not, see <https://www.gnu.org/licenses/>. 16ce74398dSGreg Roach */ 17fcfa147eSGreg Roach 18e7f56f2aSGreg Roachdeclare(strict_types=1); 19e7f56f2aSGreg Roach 20ce74398dSGreg Roachnamespace Fisharebest\Webtrees\Services; 21ce74398dSGreg Roach 22eeec557aSGreg Roachuse Fisharebest\Webtrees\Registry; 23eeec557aSGreg Roach 24ce74398dSGreg Roach/** 25ce74398dSGreg Roach * Check for PHP timeouts. 26ce74398dSGreg Roach */ 27ce74398dSGreg Roachclass TimeoutService 28ce74398dSGreg Roach{ 29c4943cffSGreg Roach //Long-running scripts run in small chunks 3016d6367aSGreg Roach private const TIME_LIMIT = 1.5; 31ce74398dSGreg Roach 32c4943cffSGreg Roach // Seconds until we run out of time 3316d6367aSGreg Roach private const TIME_UP_THRESHOLD = 3.0; 34ce74398dSGreg Roach 35c4943cffSGreg Roach // The start time of the request 36c4943cffSGreg Roach private float $start_time; 37ce74398dSGreg Roach 38ce74398dSGreg Roach /** 3924f2a3afSGreg Roach * @param float|null $start_time 40ce74398dSGreg Roach */ 41*2c6f1bd5SGreg Roach public function __construct(float|null $start_time = null) 42ce74398dSGreg Roach { 43eeec557aSGreg Roach $this->start_time = $start_time ?? Registry::timeFactory()->now(); 44ce74398dSGreg Roach } 45ce74398dSGreg Roach 46ce74398dSGreg Roach /** 47ce74398dSGreg Roach * Some long-running scripts need to know when to stop. 48ce74398dSGreg Roach * 49ce74398dSGreg Roach * @param float $threshold 50ce74398dSGreg Roach * 51ce74398dSGreg Roach * @return bool 52ce74398dSGreg Roach */ 53ce74398dSGreg Roach public function isTimeNearlyUp(float $threshold = self::TIME_UP_THRESHOLD): bool 54ce74398dSGreg Roach { 558784bbcaSGreg Roach $max_execution_time = (int) ini_get('max_execution_time'); 56ce74398dSGreg Roach 57ce74398dSGreg Roach // If there's no time limit, then we can't run out of time. 588784bbcaSGreg Roach if ($max_execution_time === 0) { 59ce74398dSGreg Roach return false; 60ce74398dSGreg Roach } 61ce74398dSGreg Roach 62eeec557aSGreg Roach $now = Registry::timeFactory()->now(); 63ce74398dSGreg Roach 648784bbcaSGreg Roach return $now + $threshold > $this->start_time + (float) $max_execution_time; 65ce74398dSGreg Roach } 66ce74398dSGreg Roach 67ce74398dSGreg Roach /** 68e669bb4bSGreg Roach * Some long-running scripts are broken down into small chunks. 69ce74398dSGreg Roach * 70ce74398dSGreg Roach * @param float $limit 71ce74398dSGreg Roach * 72ce74398dSGreg Roach * @return bool 73ce74398dSGreg Roach */ 74ce74398dSGreg Roach public function isTimeLimitUp(float $limit = self::TIME_LIMIT): bool 75ce74398dSGreg Roach { 76eeec557aSGreg Roach $now = Registry::timeFactory()->now(); 77ce74398dSGreg Roach 78ce74398dSGreg Roach return $now > $this->start_time + $limit; 79ce74398dSGreg Roach } 80ce74398dSGreg Roach} 81