1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\Lock;
13
14use Symfony\Component\Lock\Exception\UnserializableKeyException;
15
16/**
17 * Key is a container for the state of the locks in stores.
18 *
19 * @author Jérémy Derussé <jeremy@derusse.com>
20 */
21final class Key
22{
23    private $resource;
24    private $expiringTime;
25    private $state = [];
26    private $serializable = true;
27
28    public function __construct(string $resource)
29    {
30        $this->resource = $resource;
31    }
32
33    public function __toString(): string
34    {
35        return $this->resource;
36    }
37
38    public function hasState(string $stateKey): bool
39    {
40        return isset($this->state[$stateKey]);
41    }
42
43    public function setState(string $stateKey, $state): void
44    {
45        $this->state[$stateKey] = $state;
46    }
47
48    public function removeState(string $stateKey): void
49    {
50        unset($this->state[$stateKey]);
51    }
52
53    public function getState(string $stateKey)
54    {
55        return $this->state[$stateKey];
56    }
57
58    public function markUnserializable(): void
59    {
60        $this->serializable = false;
61    }
62
63    public function resetLifetime()
64    {
65        $this->expiringTime = null;
66    }
67
68    /**
69     * @param float $ttl the expiration delay of locks in seconds
70     */
71    public function reduceLifetime(float $ttl)
72    {
73        $newTime = microtime(true) + $ttl;
74
75        if (null === $this->expiringTime || $this->expiringTime > $newTime) {
76            $this->expiringTime = $newTime;
77        }
78    }
79
80    /**
81     * Returns the remaining lifetime.
82     *
83     * @return float|null Remaining lifetime in seconds. Null when the key won't expire.
84     */
85    public function getRemainingLifetime(): ?float
86    {
87        return null === $this->expiringTime ? null : $this->expiringTime - microtime(true);
88    }
89
90    public function isExpired(): bool
91    {
92        return null !== $this->expiringTime && $this->expiringTime <= microtime(true);
93    }
94
95    public function __sleep(): array
96    {
97        if (!$this->serializable) {
98            throw new UnserializableKeyException('The key can not be serialized.');
99        }
100
101        return ['resource', 'expiringTime', 'state'];
102    }
103}
104