OptimisticLockManager::releaseLock()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 7
ccs 6
cts 6
cp 1
rs 9.4286
cc 2
eloc 4
nc 2
nop 1
crap 2
1
<?php
2
3
/*
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * The software is based on the Axon Framework project which is
17
 * licensed under the Apache 2.0 license. For more information on the Axon Framework
18
 * see <http://www.axonframework.org/>.
19
 *
20
 * This software consists of voluntary contributions made by many individuals
21
 * and is licensed under the MIT license. For more information, see
22
 * <http://www.governor-framework.org/>.
23
 */
24
25
namespace Governor\Framework\Repository;
26
27
use Governor\Framework\Domain\AggregateRootInterface;
28
29
/**
30
 * Description of OptimitsticLockManager
31
 *
32
 * @author    "David Kalosi" <[email protected]>  
33
 * @license   <a href="http://www.opensource.org/licenses/mit-license.php">MIT License</a> 
34
 */
35
// TODO this should be moved to the redis extension since this cannot occur without workers
36
class OptimisticLockManager implements LockManagerInterface
37
{
38
39
    private $locks = array();
40
41 2
    public function obtainLock($aggregateIdentifier)
42
    {
43 2
        if (!array_key_exists($aggregateIdentifier, $this->locks)) {
44 2
            $this->locks[$aggregateIdentifier] = new OptimisticLock();
45 2
        }
46
        
47 2
        $lock = $this->locks[$aggregateIdentifier];
48 2
        if (!$lock->lock()) {
49
            unset($this->locks[$aggregateIdentifier]);
50
        }
51 2
    }
52
53 1
    public function releaseLock($aggregateIdentifier)
54
    {
55 1
        if (array_key_exists($aggregateIdentifier, $this->locks)) {
56 1
            $lock = $this->locks[$aggregateIdentifier];
57 1
            $lock->unlock($aggregateIdentifier, $this->locks);
58 1
        }
59 1
    }
60
61 1
    public function validateLock(AggregateRootInterface $aggregate)
62
    {
63 1
        if (array_key_exists($aggregate->getIdentifier(), $this->locks)) {
64 1
            $lock = $this->locks[$aggregate->getIdentifier()];            
65 1
            return $lock->validate($aggregate);
66
        }
67
68
        return true;
69
    }
70
71
}
72
73
class OptimisticLock
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class should be in its own file to aid autoloaders.

Having each class in a dedicated file usually plays nice with PSR autoloaders and is therefore a well established practice. If you use other autoloaders, you might not want to follow this rule.

Loading history...
74
{
75
76
    private $versionNumber;
77
    private $lockCount = 0;
78
    private $closed = false;
79
80 1
    public function validate(AggregateRootInterface $aggregate)
81
    {
82 1
        $lastCommitedScn = $aggregate->getVersion();   
83
        
84 1
        if (null === $this->versionNumber || $this->versionNumber === $lastCommitedScn) {             
85 1
            $last = (null === $lastCommitedScn) ? 0 : $lastCommitedScn;            
86 1
            $this->versionNumber = $last;            
87 1
            return true;
88
        }
89
        
90 1
        return false;
91
    }
92
93 2
    public function lock()
94
    {
95 2
        if ($this->closed) {
96
            return false;
97
        }
98
99 2
        $this->lockCount++;
100 2
        return true;
101
    }
102
103 1
    public function unlock($aggregateIdentifier, &$locks)
104
    {
105 1
        if ($this->lockCount !== 0) {
106 1
            $this->lockCount--;
107 1
        }
108
        
109 1
        if ($this->lockCount === 0) {
110 1
            $this->closed = true;
111 1
            unset($locks[$aggregateIdentifier]);
112 1
        }
113 1
    }
114
115
}
116