xref: /webtrees/app/Services/TimeoutService.php (revision 34f1e0a8ae4a1c91479b7ac0e62c93789d4c124b)
1<?php
2/**
3 * webtrees: online genealogy
4 * Copyright (C) 2018 webtrees development team
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 */
16namespace Fisharebest\Webtrees\Services;
17
18/**
19 * Check for PHP timeouts.
20 */
21class TimeoutService
22{
23    /** @var float Long-running scripts run in small chunks */
24    const TIME_LIMIT = 1.5;
25
26    /** @var float Seconds until we run out of time */
27    const TIME_UP_THRESHOLD = 3.0;
28
29    /** @var float The start time of the request */
30    private $start_time;
31
32    /**
33     * TimeoutService constructor.
34     *
35     * @param float $start_time
36     */
37    public function __construct(float $start_time)
38    {
39        $this->start_time = $start_time;
40    }
41
42    /**
43     * Some long-running scripts need to know when to stop.
44     *
45     * @param float $threshold
46     *
47     * @return bool
48     */
49    public function isTimeNearlyUp(float $threshold = self::TIME_UP_THRESHOLD): bool
50    {
51        $max_execution_time = (float) ini_get('max_execution_time');
52
53        // If there's no time limit, then we can't run out of time.
54        if ($max_execution_time === 0.0) {
55            return false;
56        }
57
58        $now = microtime(true);
59
60        return $now + $threshold > $this->start_time + $max_execution_time;
61    }
62
63    /**
64     * Some long running scripts are broken down into small chunks.
65     *
66     * @param float $limit
67     *
68     * @return bool
69     */
70    public function isTimeLimitUp(float $limit = self::TIME_LIMIT): bool
71    {
72        $now = microtime(true);
73
74        return $now > $this->start_time + $limit;
75    }
76}
77