Passed
Push — refresh_donut ( aa1285 )
by Akihito
11:35
created

AbstractDonutCacheInterceptor::invoke()   B

Complexity

Conditions 7
Paths 6

Size

Total Lines 30
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 7
eloc 17
c 2
b 0
f 0
nc 6
nop 1
dl 0
loc 30
rs 8.8333
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BEAR\QueryRepository;
6
7
use BEAR\Resource\Code;
8
use BEAR\Resource\ResourceObject;
9
use Ray\Aop\MethodInterceptor;
10
use Ray\Aop\MethodInvocation;
11
use Throwable;
12
13
use function assert;
14
use function get_class;
15
use function sprintf;
16
use function trigger_error;
17
18
use const E_USER_WARNING;
19
20
abstract class AbstractDonutCacheInterceptor implements MethodInterceptor
21
{
22
    protected const IS_ENTIRE_CONTENT_CACHEABLE = false;
23
24
    private DonutRepositoryInterface $donutRepository;
25
    private RefreshDonut $refreshDonut;
26
27
    public function __construct(DonutRepositoryInterface $donutRepository, RefreshDonut $refreshDonut)
28
    {
29
        $this->donutRepository = $donutRepository;
30
        $this->refreshDonut = $refreshDonut;
31
    }
32
33
    /**
34
     * {@inheritdoc}
35
     */
36
    final public function invoke(MethodInvocation $invocation)
37
    {
38
        $ro = $invocation->getThis();
39
        assert($ro instanceof ResourceObject);
40
        if ($this->refreshDonut->refresh) {
41
            return $invocation->proceed();
42
        }
43
44
        try {
45
            $maybeRo = $this->donutRepository->get($ro);
46
            if ($maybeRo instanceof ResourceObject) {
47
                return $maybeRo;
48
            }
49
        } catch (Throwable $e) { // @codeCoverageIgnoreStart
50
            // when cache server is down
51
            $this->triggerWarning($e);
52
53
            return $invocation->proceed(); // @codeCoverageIgnoreStartEnd
54
        }
55
56
        /** @var ResourceObject $ro */
57
        $ro = $invocation->proceed();
58
        // donut created in ResourceObject
59
        if (isset($ro->headers[Header::ETAG]) || $ro->code >= Code::BAD_REQUEST) {
60
            return $ro;
61
        }
62
63
        return static::IS_ENTIRE_CONTENT_CACHEABLE ?
64
            $this->donutRepository->putStatic($ro, null, null) :
65
            $this->donutRepository->putDonut($ro, null);
66
    }
67
68
    /**
69
     * @codeCoverageIgnore
70
     */
71
    private function triggerWarning(Throwable $e): void
72
    {
73
        trigger_error(sprintf('%s: %s in %s:%s', get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()), E_USER_WARNING);
74
    }
75
}
76