Completed
Push — master ( 4e3a1b...06a217 )
by Narcotic
22:41
created

CollectionCache   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 176
Duplicated Lines 13.07 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 72%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 15
c 1
b 0
f 0
lcom 1
cbo 4
dl 23
loc 176
ccs 36
cts 50
cp 0.72
rs 10

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A buildCacheKey() 0 4 1
A getCollectionCacheTime() 0 7 2
A getByRepository() 13 13 3
A setByRepository() 10 10 2
A updateOperationCheck() 0 13 2
A addUpdateLock() 0 9 1
A releaseUpdateLock() 0 14 2
A setConfiguration() 0 4 1

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/**
3
 * ExtReferenceConverter class file
4
 */
5
6
namespace Graviton\DocumentBundle\Service;
7
8
use Doctrine\Common\Cache\CacheProvider;
9
use Doctrine\ODM\MongoDB\DocumentRepository as Repository;
10
use Monolog\Logger;
11
12
/**
13
 * graviton.cache.collections
14
15
 * Collection Cache Service
16
 *
17
 *
18
 *
19
 * @author   List of contributors <https://github.com/libgraviton/graviton/graphs/contributors>
20
 * @license  http://opensource.org/licenses/gpl-license.php GNU Public License
21
 * @link     http://swisscom.ch
22
 */
23
class CollectionCache
24
{
25
    /** Prefix cache key */
26
    const BASE_KEY = 'CollectionCache';
27
28
    /** Prefix cache key */
29
    const BASE_UPDATE_KEY = 'CollectionUpdate';
30
31
    /** @var array  */
32
    private $config = [];
33
34
    /** @var CacheProvider */
35
    private $cache;
36
37
    /**
38
     * @var Logger
39
     */
40
    private $logger;
41
42
    /**
43
     * CollectionCache constructor.
44
     * @param CacheProvider $cache         Cache provider
45
     * @param Logger        $logger        Logger
46
     * @param array         $configuration Collections to be saved
47
     */
48 10
    public function __construct(
49
        CacheProvider $cache,
50
        Logger $logger,
51
        $configuration
52
    ) {
53 10
        $this->cache = $cache;
54 10
        $this->logger = $logger;
55 10
        $this->config = $configuration;
56 10
    }
57
58
    /**
59
     * Makes an id
60
     *
61
     * @param string $collection DB collection name
62
     * @param string $id         Object Identifier
63
     * @return string
64
     */
65 6
    private function buildCacheKey($collection, $id)
66
    {
67 6
        return self::BASE_KEY.'-'.preg_replace("/[^a-zA-Z0-9_-]+/", "-", $collection.'-'.$id);
68
    }
69
70
    /**
71
     * Time it should be in cache and if so should happen
72
     *
73
     * @param string $collection DB collection name
74
     * @return int
75
     */
76 6
    private function getCollectionCacheTime($collection)
77
    {
78 6
        if (array_key_exists($collection, $this->config)) {
79 4
            return (int) $this->config[$collection];
80
        }
81 2
        return 0;
82
    }
83
84
    /**
85
     * Return un cached object.
86
     *
87
     * @param Repository $repository DB Repository
88
     * @param string     $id         Queried is
89
     * @return object|false if no cache found
90
     */
91 2 View Code Duplication
    public function getByRepository(Repository $repository, $id)
92
    {
93 2
        $collection = $repository->getClassMetadata()->collection;
94 2
        if (!$this->getCollectionCacheTime($collection)) {
95
            return false;
96
        }
97 2
        $key = $this->buildCacheKey($collection, $id);
98
99 2
        if ($result = $this->cache->fetch($key)) {
100 2
            return $result;
101
        }
102
        return false;
103
    }
104
105
    /**
106
     * @param Repository $repository DB Repository
107
     * @param string     $serialized Serialised Object document
108
     * @param string     $id         Object document identifier
109
     * @return bool
110
     */
111 4 View Code Duplication
    public function setByRepository(Repository $repository, $serialized, $id)
112
    {
113 4
        $collection = $repository->getClassMetadata()->collection;
114 4
        if (!$time = $this->getCollectionCacheTime($collection)) {
115 2
            return false;
116
        }
117 2
        $key = $this->buildCacheKey($collection, $id);
118
119 2
        return $this->cache->save($key, $serialized, $time);
120
    }
121
122
    /**
123
     * Will sleep until previous operation has finished.
124
     * Default sleep time 10 seconds.
125
     * Loops by 1/4 second while there is a cache update lock
126
     *
127
     * @param Repository $repository Model repository
128
     * @param string     $id         Object identifier
129
     *
130
     * @return void
131
     */
132 2
    public function updateOperationCheck(Repository $repository, $id)
133
    {
134 2
        $collection = $repository->getClassMetadata()->collection;
135
136 2
        $key = self::BASE_UPDATE_KEY.'-'.$this->buildCacheKey($collection, $id);
137 2
        $this->logger->info("LOCK CHECK START = ".$collection.", id = ".$id. ", key=".$key);
138
139 2
        while ($this->cache->fetch($key)) {
140 2
            usleep(250000);
141
        }
142
143 2
        $this->logger->info("LOCK CHECK FINISHED = ".$collection.", id = ".$id. ", key=".$key);
144 2
    }
145
146
    /**
147
     * Will add update lock
148
     *
149
     * @param Repository $repository Model repository
150
     * @param string     $id         Object identifier
151
     * @param integer    $maxTime    Set timeout for lock
152
     *
153
     * @return bool
154
     */
155 2
    public function addUpdateLock(Repository $repository, $id, $maxTime = 10)
156
    {
157 2
        $collection = $repository->getClassMetadata()->collection;
158 2
        $key = self::BASE_UPDATE_KEY.'-'.$this->buildCacheKey($collection, $id);
159
160 2
        $this->logger->info("LOCK ADD = ".$collection.", id = ".$id. ", key=".$key);
161
162 2
        return $this->cache->save($key, true, $maxTime);
163
    }
164
165
    /**
166
     * Will remove lock if there was one.
167
     *
168
     * @param Repository $repository Model repository
169
     * @param string     $id         Object identifier
170
     *
171
     * @return void
172
     */
173
    public function releaseUpdateLock(Repository $repository, $id)
174
    {
175
        $collection = $repository->getClassMetadata()->collection;
176
        $baseKey = $this->buildCacheKey($collection, $id);
177
        $key = self::BASE_UPDATE_KEY.'-'.$baseKey;
178
179
        $this->cache->delete($key);
180
181
        $this->logger->info("LOCK RELEASE = ".$collection.", id = ".$id. ", key=".$key);
182
183
        if ($this->getCollectionCacheTime($collection)) {
184
            $this->cache->delete($baseKey);
185
        }
186
    }
187
188
    /**
189
     * Update cache if needed
190
     *
191
     * @param array $configuration configuration array
192
     * @return void
193
     */
194
    public function setConfiguration($configuration)
195
    {
196
        $this->config = $configuration;
197
    }
198
}
199