GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 46877f...42b2a8 )
by Rémi
04:05
created

SingleStoreLocker::waitBeforeRetrying()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace RemiSan\Lock\Locker;
4
5
use RemiSan\Lock\LockStore;
6
use RemiSan\Lock\Exceptions\LockingException;
7
use RemiSan\Lock\Exceptions\UnlockingException;
8
use RemiSan\Lock\Lock;
9
use RemiSan\Lock\Locker;
10
use RemiSan\Lock\TokenGenerator;
11
use Symfony\Component\Stopwatch\Stopwatch;
12
13
final class SingleStoreLocker implements Locker
14
{
15
    /** @var LockStore */
16
    private $store;
17
18
    /** @var TokenGenerator */
19
    private $tokenGenerator;
20
21
    /** @var Stopwatch */
22
    private $stopwatch;
23
24
    /**
25
     * SingleStoreLocker constructor.
26
     *
27
     * @param LockStore      $store          The persisting store for the locks
28
     * @param TokenGenerator $tokenGenerator The token generator
29
     * @param Stopwatch      $stopwatch      A way to measure time passed
30
     */
31
    public function __construct(
32
        $store,
33
        TokenGenerator $tokenGenerator,
34
        Stopwatch $stopwatch
35
    ) {
36
        $this->store = $store;
37
        $this->tokenGenerator = $tokenGenerator;
38
        $this->stopwatch = $stopwatch;
39
    }
40
41
    /**
42
     * {@inheritdoc}
43
     */
44
    public function lock($resource, $ttl = null, $retryDelay = 0, $retryCount = 0)
45
    {
46
        $lock = new Lock((string) $resource, $this->tokenGenerator->generateToken());
47
48
        $tried = 0;
49
        while (true) {
50
            try {
51
                return $this->lockAndCheckQuorumAndTtl($lock, $ttl);
52
            } catch (LockingException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
53
            }
54
55
            if ($tried++ === $retryCount) {
56
                break;
57
            }
58
59
            $this->waitBeforeRetrying($retryDelay);
60
        }
61
62
        throw new LockingException('Failed locking the resource.');
63
    }
64
65
    /**
66
     * {@inheritdoc}
67
     */
68
    public function isLocked($resource)
69
    {
70
        return $this->store->exists((string) $resource);
71
    }
72
73
    /**
74
     * {@inheritdoc}
75
     */
76
    public function unlock(Lock $lock)
77
    {
78
        if (!$this->store->delete($lock)) {
79
            if ($this->store->exists($lock->getResource())) {
80
                // Only throw an exception if the lock is still present
81
                throw new UnlockingException('Failed releasing the lock.');
82
            }
83
        }
84
    }
85
86
    /**
87
     * Try locking resource on store.
88
     *
89
     * Measure the time to do it and reject if time to lock on store have exceeded the ttl.
90
     *
91
     * @param Lock $lock The lock instance
92
     * @param int  $ttl  Time to live in milliseconds
93
     *
94
     * @throws LockingException
95
     *
96
     * @return Lock
97
     */
98
    private function lockAndCheckQuorumAndTtl(Lock $lock, $ttl)
99
    {
100
        $timeMeasure = $this->stopwatch->start($lock->getToken());
101
        $this->store->set($lock, $ttl);
102
        $timeMeasure->stop();
103
104
        if ($ttl) {
105
            $this->checkTtl($timeMeasure->getDuration(), $ttl);
106
            $lock->setValidityEndTime($timeMeasure->getOrigin() + $ttl);
107
        }
108
109
        return $lock;
110
    }
111
112
    /**
113
     * Make the script wait before retrying to lock.
114
     *
115
     * @param int $retryDelay The retry delay in milliseconds
116
     */
117
    private function waitBeforeRetrying($retryDelay)
118
    {
119
        usleep($retryDelay * 1000);
120
    }
121
122
    /**
123
     * Checks if the elapsed time is inferior to the ttl.
124
     *
125
     * To the elapsed time is added a drift time to have a margin of error.
126
     * If this adjusted time is greater than the ttl, it will throw a LockingException.
127
     *
128
     * @param int $elapsedTime The time elapsed in milliseconds
129
     * @param int $ttl         The time to live in milliseconds
130
     *
131
     * @throws LockingException
132
     */
133
    private function checkTtl($elapsedTime, $ttl)
134
    {
135
        $adjustedElapsedTime = $elapsedTime + $this->store->getDrift($ttl);
136
137
        if ($adjustedElapsedTime >= $ttl) {
138
            throw new LockingException('Time to lock the resource has exceeded the ttl.');
139
        }
140
    }
141
}
142