1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\ArchiveProcessor;
use Piwik\Common;
use Piwik\Concurrency\Lock;
use Piwik\Concurrency\LockBackend;
use Piwik\Container\StaticContainer;
use Piwik\SettingsPiwik;
class ArchivingStatus
{
const LOCK_KEY_PREFIX = 'Archiving';
const DEFAULT_ARCHIVING_TTL = 7200; // 2 hours
/**
* @var LockBackend
*/
private $lockBackend;
/**
* @var int
*/
private $archivingTTLSecs;
/**
* @var Lock[]
*/
private $lockStack = [];
private $pid;
public function __construct(LockBackend $lockBackend, $archivingTTLSecs = self::DEFAULT_ARCHIVING_TTL)
{
$this->lockBackend = $lockBackend;
$this->archivingTTLSecs = $archivingTTLSecs;
$this->pid = Common::getProcessId();
}
public function archiveStarted(Parameters $params)
{
$lock = $this->makeArchivingLock($params);
$lock->acquireLock($this->getInstanceProcessId(), $this->archivingTTLSecs);
array_push($this->lockStack, $lock);
}
public function archiveFinished()
{
$lock = array_pop($this->lockStack);
$lock->unlock();
}
public function getCurrentArchivingLock()
{
if (empty($this->lockStack)) {
return null;
}
return end($this->lockStack);
}
public function getSitesCurrentlyArchiving()
{
$lockMeta = new Lock($this->lockBackend, self::LOCK_KEY_PREFIX . '.');
$acquiredLocks = $lockMeta->getAllAcquiredLockKeys();
$sitesCurrentlyArchiving = [];
foreach ($acquiredLocks as $lockKey) {
$parts = explode('.', $lockKey);
if (!isset($parts[1])) {
continue;
}
$sitesCurrentlyArchiving[] = (int) $parts[1];
}
$sitesCurrentlyArchiving = array_unique($sitesCurrentlyArchiving);
$sitesCurrentlyArchiving = array_values($sitesCurrentlyArchiving);
return $sitesCurrentlyArchiving;
}
/**
* @return Lock
*/
private function makeArchivingLock(Parameters $params)
{
$doneFlag = Rules::getDoneStringFlagFor([$params->getSite()->getId()], $params->getSegment(),
$params->getPeriod()->getLabel(), $params->getRequestedPlugin());
$lockKeyParts = [
self::LOCK_KEY_PREFIX,
$params->getSite()->getId(),
// md5 to keep it within the 70 char limit in the table
md5($params->getPeriod()->getId() . $params->getPeriod()->getRangeString() . $doneFlag),
];
$lockKeyPrefix = implode('.', $lockKeyParts);
return new Lock(StaticContainer::get(LockBackend::class), $lockKeyPrefix, $this->archivingTTLSecs);
}
private function getInstanceProcessId()
{
return SettingsPiwik::getPiwikInstanceId() . '.' . $this->pid;
}
}
|