Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
4.17% |
1 / 24 |
|
16.67% |
1 / 6 |
CRAP | |
0.00% |
0 / 1 |
LockService | |
4.17% |
1 / 24 |
|
16.67% |
1 / 6 |
213.03 | |
0.00% |
0 / 1 |
getLockFactory | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
6 | |||
getStore | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
42 | |||
install | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRedisStore | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
getFlockStore | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
12 | |||
getNoLockStore | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | /** |
4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public License |
6 | * as published by the Free Software Foundation; under version 2 |
7 | * of the License (non-upgradable). |
8 | * |
9 | * This program is distributed in the hope that it will be useful, |
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. |
13 | * |
14 | * You should have received a copy of the GNU General Public License |
15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
17 | * |
18 | * Copyright (c) 2019 (original work) Open Assessment Technologies SA; |
19 | * |
20 | * |
21 | */ |
22 | |
23 | namespace oat\oatbox\mutex; |
24 | |
25 | use oat\oatbox\service\ConfigurableService; |
26 | use Symfony\Component\Lock\Factory; |
27 | use Symfony\Component\Lock\Store\FlockStore; |
28 | use Symfony\Component\Lock\Store\RedisStore; |
29 | use Symfony\Component\Lock\StoreInterface; |
30 | use Symfony\Component\Lock\Store\RetryTillSaveStore; |
31 | |
32 | /** |
33 | * Class LockService |
34 | * |
35 | * Service is used to configure and create lock factory. |
36 | * See https://symfony.com/doc/current/components/lock.html for more details |
37 | * |
38 | * @package oat\oatbox\mutex |
39 | * @author Aleh Hutnikau, <hutnikau@1pt.com> |
40 | */ |
41 | class LockService extends ConfigurableService |
42 | { |
43 | public const SERVICE_ID = 'generis/LockService'; |
44 | public const OPTION_PERSISTENCE_CLASS = 'persistence_class'; |
45 | public const OPTION_PERSISTENCE_OPTIONS = 'persistence_options'; |
46 | |
47 | /** @var Factory */ |
48 | private $factory; |
49 | |
50 | /** @var StoreInterface */ |
51 | private $store; |
52 | |
53 | /** |
54 | * @return Factory |
55 | * @throws \common_exception_FileReadFailedException |
56 | * @throws \common_exception_InconsistentData |
57 | * @throws \common_exception_NotImplemented |
58 | */ |
59 | public function getLockFactory() |
60 | { |
61 | if ($this->factory === null) { |
62 | $this->factory = new Factory(new RetryTillSaveStore($this->getStore())); |
63 | } |
64 | return $this->factory; |
65 | } |
66 | |
67 | /** |
68 | * @return StoreInterface |
69 | * @throws \common_exception_FileReadFailedException |
70 | * @throws \common_exception_InconsistentData |
71 | * @throws \common_exception_NotImplemented |
72 | */ |
73 | private function getStore() |
74 | { |
75 | if ($this->store === null) { |
76 | $persistenceClass = $this->getOption(self::OPTION_PERSISTENCE_CLASS); |
77 | $persistenceOptions = $this->getOption(self::OPTION_PERSISTENCE_OPTIONS); |
78 | |
79 | switch ($persistenceClass) { |
80 | case FlockStore::class: |
81 | $this->store = $this->getFlockStore($persistenceOptions); |
82 | break; |
83 | case NoLockStorage::class: |
84 | $this->store = $this->getNoLockStore(); |
85 | break; |
86 | case RedisStore::class: |
87 | $this->store = $this->getRedisStore($persistenceOptions); |
88 | break; |
89 | default: |
90 | throw new \common_exception_NotImplemented('configured storage is not supported'); |
91 | } |
92 | } |
93 | |
94 | return $this->store; |
95 | } |
96 | |
97 | /** |
98 | * Install store. Should be called after registration of lock service |
99 | */ |
100 | public function install() |
101 | { |
102 | } |
103 | |
104 | /** |
105 | * @param $persistenceId |
106 | * @return RedisStore |
107 | * @throws \common_exception_InconsistentData |
108 | */ |
109 | private function getRedisStore($persistenceId) |
110 | { |
111 | $persistenceManager = $this->getServiceLocator()->get(\common_persistence_Manager::SERVICE_ID); |
112 | $persistence = $persistenceManager->getPersistenceById($persistenceId); |
113 | if (!$persistence->getDriver() instanceof \common_persistence_PhpRedisDriver) { |
114 | throw new \common_exception_InconsistentData('Not redis persistence id configured for RedisStore'); |
115 | } |
116 | return new RedisStore($persistence->getDriver()->getConnection()); |
117 | } |
118 | |
119 | /** |
120 | * @param $filePath |
121 | * @return FlockStore |
122 | * @throws \common_exception_FileReadFailedException |
123 | */ |
124 | private function getFlockStore($filePath) |
125 | { |
126 | if (is_dir($filePath) && is_writable($filePath)) { |
127 | return new FlockStore($filePath); |
128 | } |
129 | throw new \common_exception_FileReadFailedException('Lock store path is not writable'); |
130 | } |
131 | |
132 | /** |
133 | * @return NoLockStorage |
134 | */ |
135 | private function getNoLockStore() |
136 | { |
137 | return new NoLockStorage(); |
138 | } |
139 | } |