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 ( e97bb7...5f2eb5 )
by Pascal
10:40 queued 09:38
created

CheckerState::retryIsAllowed()   B

Complexity

Conditions 6
Paths 5

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
c 0
b 0
f 0
rs 8.9457
cc 6
nc 5
nop 0
1
<?php
2
3
namespace ProtoneMedia\ApiHealth\Storage;
4
5
use Illuminate\Notifications\Notification;
6
use Illuminate\Support\Facades\Cache;
7
use ProtoneMedia\ApiHealth\Checkers\Checker;
8
use ProtoneMedia\ApiHealth\Checkers\CheckerAllowsForRetries;
9
use ProtoneMedia\ApiHealth\Checkers\CheckerHasFailed;
10
use ProtoneMedia\ApiHealth\Events\CheckerHasFailed as CheckerHasFailedEvent;
11
use ProtoneMedia\ApiHealth\Events\CheckerHasRecovered;
12
use ProtoneMedia\ApiHealth\Events\CheckerIsStillFailing;
13
14
class CheckerState
15
{
16
    /**
17
     * The checker.
18
     *
19
     * @var \ProtoneMedia\ApiHealth\Checkers\Checker
20
     */
21
    private $checker;
22
23
    /**
24
     * The cache driver instance.
25
     *
26
     * @var \Illuminate\Contracts\Cache\Repository
27
     */
28
    private $cache;
29
30
    public function __construct(Checker $checker)
31
    {
32
        $this->checker = $checker;
33
34
        $this->cache = Cache::driver(config('api-health.cache_driver'));
35
    }
36
37
    /**
38
     * Shortcut for creating an instance with the given checker class.
39
     *
40
     * @param  string $checkerClass
41
     * @return \ProtoneMedia\ApiHealth\Storage\CheckerState
42
     */
43
    public static function make(string $checkerClass)
44
    {
45
        return new static($checkerClass::create());
46
    }
47
48
    /**
49
     * Returns the cache key for this checker.
50
     *
51
     * @return string
52
     */
53
    private function key(): string
54
    {
55
        return 'laravel-api-checker.' . $this->checker->id();
56
    }
57
58
    /**
59
     * Returns a boolean wether any data has been stored.
60
     *
61
     * @return bool
62
     */
63
    public function exists(): bool
64
    {
65
        return $this->cache->has($this->key());
66
    }
67
68
    /**
69
     * Stores the given data into the cache repository.
70
     *
71
     * @param  array  $data
72
     * @return null
73
     */
74
    private function store(array $data)
75
    {
76
        $this->cache->forever($this->key(), $data);
77
    }
78
79
    /**
80
     * Returns all stored data.
81
     *
82
     * @return array
83
     */
84
    public function data(): array
85
    {
86
        return $this->cache->get($this->key());
87
    }
88
89
    /**
90
     * Returns a boolean wether the state is set to failed.
91
     *
92
     * @return bool
93
     */
94
    public function isFailing(): bool
95
    {
96
        return $this->data()['failed_at'] ? true : false;
97
    }
98
99
    /**
100
     * Returns a boolean wether the state is set to passes.
101
     *
102
     * @return bool
103
     */
104
    public function isPassing(): bool
105
    {
106
        return $this->data()['passed_at'] ? true : false;
107
    }
108
109
    /**
110
     * Determinates if a failed notification should be sent.
111
     *
112
     * @return bool
113
     */
114
    public function shouldSentFailedNotification(): bool
115
    {
116
        $sentNotifications = collect($this->data()['notifications_sent']);
117
118
        if ($sentNotifications->isEmpty()) {
119
            return true;
120
        }
121
122
        if (!$resendAfterMinutes = $this->checker->resendFailedNotificationAfterMinutes()) {
123
            return false;
124
        }
125
126
        $diffInSeconds = now()->getTimestamp() - $sentNotifications->last()['sent_at'];
127
128
        return $diffInSeconds >= ($resendAfterMinutes * 60);
129
    }
130
131
    /**
132
     * Determinates wether the checker is allowed to do another retry.
133
     *
134
     * @return bool
135
     */
136
    public function retryIsAllowed(): bool
137
    {
138
        if (!$this->checker instanceof CheckerAllowsForRetries) {
139
            return false;
140
        }
141
142
        if ($this->exists() && $this->isFailing()) {
143
            return false;
144
        }
145
146
        if (!$allowedRetries = $this->checker->allowedRetries()) {
147
            return false;
148
        }
149
150
        if (!$this->exists()) {
151
            return true;
152
        }
153
154
        $retries = $this->data()['retried_at'];
155
156
        return $allowedRetries > count($retries);
157
    }
158
159
    /**
160
     * Set the state to failed with the given exception message.
161
     *
162
     * @param \ProtoneMedia\ApiHealth\Checkers\CheckerHasFailed $exception
163
     */
164
    public function setToFailed(CheckerHasFailed $exception)
165
    {
166
        $this->store($failedData = [
167
            'exception_message'  => $exception->getMessage(),
168
            'passed_at'          => null,
169
            'failed_at'          => [now()->getTimestamp()],
170
            'notifications_sent' => [],
171
        ]);
172
173
        event(new CheckerHasFailedEvent($this->checker, $exception, $failedData));
174
    }
175
176
    /**
177
     * Adds the current timestamp to the failed state.
178
     *
179
     * @param \ProtoneMedia\ApiHealth\Checkers\CheckerHasFailed $exception
180
     */
181
    public function addFailedTimestamp(CheckerHasFailed $exception)
182
    {
183
        $failedData = $this->data();
184
185
        $failedData['failed_at'][] = now()->getTimestamp();
186
187
        $this->store($failedData);
188
189
        event(new CheckerIsStillFailing($this->checker, $exception, $failedData));
190
    }
191
192
    /**
193
     * Adds the current timestamp to the retry array.
194
     *
195
     * @return null
196
     */
197
    public function addRetryTimestamp()
198
    {
199
        $data = $this->data();
200
201
        $data['retried_at'][] = now()->getTimestamp();
202
203
        $this->store($data);
204
    }
205
206
    /**
207
     * Adds the current timestamp to the array of sent notifications.
208
     *
209
     * @param  \Illuminate\Notifications\Notification $notification
210
     * @return null
211
     */
212
    public function markSentFailedNotification(Notification $notification)
213
    {
214
        $data = $this->data();
215
216
        $data['notifications_sent'][] = [
217
            'notification_type' => get_class($notification),
218
            'sent_at'           => now()->getTimestamp(),
219
        ];
220
221
        $this->store($data);
222
    }
223
224
    /**
225
     * Set the state to passes.
226
     * @return null
227
     */
228
    public function setToPassing()
229
    {
230
        $failedData = ($this->exists() && $this->isFailing()) ? $this->data() : null;
231
232
        $this->store([
233
            'exception_message'  => null,
234
            'passed_at'          => now()->getTimestamp(),
235
            'failed_at'          => null,
236
            'notifications_sent' => [],
237
            'retried_at'         => [],
238
        ]);
239
240
        $failedData ? event(new CheckerHasRecovered($this->checker, $failedData)) : null;
241
    }
242
}
243