summaryrefslogtreecommitdiff
path: root/vendor/open-telemetry/sdk/Metrics/StalenessHandler/DelayedStalenessHandlerFactory.php
blob: 0d719c74f7fe66933e47ee6992d7729c84d6f0f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<?php

declare(strict_types=1);

namespace OpenTelemetry\SDK\Metrics\StalenessHandler;

use ArrayAccess;
use Closure;
use OpenTelemetry\SDK\Common\Time\ClockInterface;
use OpenTelemetry\SDK\Common\Util\WeakMap;
use OpenTelemetry\SDK\Metrics\StalenessHandlerFactoryInterface;
use OpenTelemetry\SDK\Metrics\StalenessHandlerInterface;
use Traversable;

final class DelayedStalenessHandlerFactory implements StalenessHandlerFactoryInterface
{
    private ClockInterface $clock;
    private int $nanoDelay;

    private Closure $stale;
    private Closure $freshen;

    /** @var ArrayAccess<DelayedStalenessHandler, int>&Traversable<DelayedStalenessHandler, int> */
    private $staleHandlers;

    /**
     * @param float $delay delay in seconds
     */
    public function __construct(ClockInterface $clock, float $delay)
    {
        $this->clock = $clock;
        $this->nanoDelay = (int) ($delay * 1e9);

        $this->stale = function (DelayedStalenessHandler $handler): void {
            $this->staleHandlers[$handler] = $this->clock->now();
        };
        $this->freshen = function (DelayedStalenessHandler $handler): void {
            unset($this->staleHandlers[$handler]);
        };

        $this->staleHandlers = WeakMap::create();
    }

    public function create(): StalenessHandlerInterface
    {
        $this->triggerStaleHandlers();

        return new DelayedStalenessHandler($this->stale, $this->freshen);
    }

    private function triggerStaleHandlers(): void
    {
        $expired = $this->clock->now() - $this->nanoDelay;
        foreach ($this->staleHandlers as $handler => $timestamp) {
            if ($timestamp > $expired) {
                break;
            }

            /** @var DelayedStalenessHandler $handler */
            unset($this->staleHandlers[$handler]);
            $handler->triggerStale();
        }
    }
}