Passed
Push — master ( c0a3a7...3b84a4 )
by Jeroen
58:51
created

Mutex::lock()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 1
dl 0
loc 12
rs 9.4285
c 0
b 0
f 0
ccs 0
cts 8
cp 0
crap 6
1
<?php
2
3
namespace Elgg\Database;
4
5
/**
6
 * WARNING: API IN FLUX. DO NOT USE DIRECTLY.
7
 *
8
 * Provides database mutex that can be used to prevent race conditions
9
 * between two processes that affect the same data.
10
 *
11
 * @access private
12
 * @since 2.1.0
13
 */
14
class Mutex {
15
16
	/**
17
	 * @var \Elgg\Database
18
	 */
19
	private $db;
20
21
	/**
22
	 * @var \Elgg\Logger
23
	 */
24
	private $logger;
25
26
	/**
27
	 * Constructor
28
	 *
29
	 * @param \Elgg\Database $db     Database
30
	 * @param \Elgg\Logger   $logger Logger
31
	 */
32 2
	public function __construct(\Elgg\Database $db, \Elgg\Logger $logger) {
33 2
		$this->db = $db;
34 2
		$this->logger = $logger;
35 2
	}
36
37
	/**
38
	 * Creates a table {prefix}{$namespace}_lock that is used as a mutex.
39
	 *
40
	 * @param string $namespace Allows having separate locks for separate processes
41
	 * @return bool
42
	 */
43
	public function lock($namespace) {
44
		$this->assertNamespace($namespace);
45
46
		if (!$this->isLocked($namespace)) {
47
			// Lock it
48
			$this->db->insertData("CREATE TABLE {$this->db->prefix}{$namespace}_lock (id INT)");
49
			$this->logger->info("Locked mutex for $namespace");
50
			return true;
51
		}
52
53
		$this->logger->warn("Cannot lock mutex for {$namespace}: already locked.");
54
		return false;
55
	}
56
57
	/**
58
	 * Unlocks mutex
59
	 *
60
	 * @param string $namespace Namespace to use for the database table
61
	 * @return void
62
	 */
63
	public function unlock($namespace) {
64
		$this->assertNamespace($namespace);
65
66
		$this->db->deleteData("DROP TABLE {$this->db->prefix}{$namespace}_lock");
67
		$this->logger->notice("Mutex unlocked for $namespace.");
68
	}
69
70
	/**
71
	 * Checks if mutex is locked
72
	 *
73
	 * @param string $namespace Namespace to use for the database table
74
	 * @return bool
75
	 */
76
	public function isLocked($namespace) {
77
		$this->assertNamespace($namespace);
78
79
		return (bool) count($this->db->getData("SHOW TABLES LIKE '{$this->db->prefix}{$namespace}_lock'"));
80
	}
81
82
	/**
83
	 * Assert that the namespace contains only characters [A-Za-z]
84
	 *
85
	 * @param string $namespace Namespace to use for the database table
86
	 * @throws InvalidParameterException
87
	 * @return void
88
	 */
89
	private function assertNamespace($namespace) {
90
		if (!ctype_alpha($namespace)) {
91
			throw new InvalidParameterException("Mutex namespace can only have characters [A-Za-z].");
0 ignored issues
show
Bug introduced by Juho Jaakkola
The type Elgg\Database\InvalidParameterException was not found. Did you mean InvalidParameterException? If so, make sure to prefix the type with \.
Loading history...
92
		}
93
	}
94
}
95