Completed
Pull Request — master (#1)
by Alexander
04:35
created

RedisLockStrategy::__construct()   C

Complexity

Conditions 8
Paths 24

Size

Total Lines 40
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 8.0421

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 40
ccs 21
cts 23
cp 0.913
rs 5.3846
cc 8
eloc 22
nc 24
nop 1
crap 8.0421
1
<?php
2
3
namespace Tourstream\RedisLockStrategy;
4
5
/***************************************************************
6
 *  Copyright notice
7
 *
8
 *  (c) 2017 Alexander Miehe ([email protected])
9
 *  All rights reserved
10
 *
11
 *  You may not remove or change the name of the author above. See:
12
 *  http://www.gnu.org/licenses/gpl-faq.html#IWantCredit
13
 *
14
 *  This script is part of the Typo3 project. The Typo3 project is
15
 *  free software; you can redistribute it and/or modify
16
 *  it under the terms of the GNU General Public License as published by
17
 *  the Free Software Foundation; either version 3 of the License, or
18
 *  (at your option) any later version.
19
 *
20
 *  The GNU General Public License can be found at
21
 *  http://www.gnu.org/copyleft/gpl.html.
22
 *  A copy is found in the LICENSE and distributed with these scripts.
23
 *
24
 *
25
 *  This script is distributed in the hope that it will be useful,
26
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
27
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28
 *  GNU General Public License for more details.
29
 *
30
 *  This copyright notice MUST APPEAR in all copies of the script!
31
 ***************************************************************/
32
33
use TYPO3\CMS\Core\Locking\Exception;
34
use TYPO3\CMS\Core\Locking\LockingStrategyInterface;
35
36
/**
37
 * @author Alexander Miehe <[email protected]>
38
 */
39
class RedisLockStrategy implements LockingStrategyInterface
40
{
41
    /**
42
     * @var \Redis
43
     */
44
    private $redis;
45
46
    /**
47
     * @var string
48
     */
49
    private $subject;
50
51
    /**
52
     * @var int
53
     */
54
    private $ttl;
55
56
    /**
57
     * @inheritdoc
58
     */
59 9
    public function __construct($subject)
60
    {
61 9
        $config = null;
62
63 9
        if (\array_key_exists('redis_lock', $GLOBALS['TYPO3_CONF_VARS']['SYS'])) {
64 8
            $config = $GLOBALS['TYPO3_CONF_VARS']['SYS']['redis_lock'];
65
        }
66
67 9
        if (!\is_array($config)) {
68 2
            throw new Exception('no configuration for redis lock strategy found');
69
        }
70
71 7
        if (!\array_key_exists('host', $config)) {
72 1
            throw new Exception('no host for redis lock strategy found');
73
        }
74 6
        $port = 6379;
75
76 6
        if (\array_key_exists('port', $config)) {
77 5
            $port = (int) $config['port'];
78
        }
79
80 6
        if (!\array_key_exists('database', $config)) {
81 1
            throw new Exception('no database for redis lock strategy found');
82
        }
83
84 5
        $this->ttl = 360;
85 5
        if (\array_key_exists('ttl', $config)) {
86
            $this->ttl = (int) $config['ttl'];
87
        }
88
89 5
        $this->subject = $subject;
90 5
        $this->redis   = new \Redis();
91 5
        $this->redis->connect($config['host'], $port);
92
93 5
        if (\array_key_exists('auth', $config)) {
94
            $this->redis->auth($config['auth']);
95
        }
96
97 5
        $this->redis->select((int) $config['database']);
98 5
    }
99
100
    /**
101
     * @inheritdoc
102
     */
103 9
    public static function getCapabilities()
104
    {
105 9
        return self::LOCK_CAPABILITY_EXCLUSIVE | self::LOCK_CAPABILITY_NOBLOCK;
106
    }
107
108
    /**
109
     * @inheritdoc
110
     */
111 9
    public static function getPriority()
112
    {
113 9
        return 100;
114
    }
115
116
    /**
117
     * @inheritdoc
118
     */
119 2
    public function acquire($mode = self::LOCK_CAPABILITY_EXCLUSIVE)
120
    {
121 2
        if ($this->isAcquired()) {
122 1
            return true;
123
        }
124
125 1
        return $this->redis->set($this->subject, uniqid(), $this->ttl);
126
    }
127
128
    /**
129
     * @inheritdoc
130
     */
131 5
    public function isAcquired()
132
    {
133 5
        return $this->redis->exists($this->subject);
134
    }
135
136
    /**
137
     * @inheritdoc
138
     */
139 2
    public function destroy()
140
    {
141 2
        $this->release();
142 2
    }
143
144
    /**
145
     * @inheritdoc
146
     */
147 2
    public function release()
148
    {
149 2
        if (!$this->isAcquired()) {
150 1
            return true;
151
        }
152
153 1
        return $this->redis->del($this->subject) === 1;
154
    }
155
156
}