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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
<?php
/**
* Matomo - free/libre analytics platform
*
* @link https://matomo.org
* @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\ArchiveProcessor;
use Piwik\Concurrency\Lock;
use Piwik\Concurrency\LockBackend;
use Piwik\Container\StaticContainer;
class ArchivingStatus
{
public const LOCK_KEY_PREFIX = 'Archiving';
public const DEFAULT_ARCHIVING_TTL = 7200; // 2 hours
/**
* @var LockBackend
*/
private $lockBackend;
/**
* @var int
*/
private $archivingTTLSecs;
/**
* @var Lock[]
*/
private $lockStack = [];
public function __construct(LockBackend $lockBackend, $archivingTTLSecs = self::DEFAULT_ARCHIVING_TTL)
{
$this->lockBackend = $lockBackend;
$this->archivingTTLSecs = $archivingTTLSecs;
}
public function archiveStarted(Parameters $params)
{
$lock = $this->makeArchivingLock($params);
$locked = $lock->acquireLock('', $this->archivingTTLSecs);
if ($locked) {
array_push($this->lockStack, $lock);
}
return $locked;
}
/**
* Try to acquire the lock that is acquired before starting archiving. If it is acquired, it
* means archiving is not ongoing. If it is not acquired, then archiving is ongoing.
*
* @param int $idSite
* @param string $date1
* @param string $date2
* @param string $period
* @param string $doneFlag
* @return Lock
*/
public function acquireArchiveInProgressLock($idSite, $date1, $date2, $period, $doneFlag)
{
$lock = $this->makeArchivingLockFromDoneFlag($idSite, $date1, $date2, $period, $doneFlag);
$lock->acquireLock('', $ttl = 1);
return $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()
);
return $this->makeArchivingLockFromDoneFlag(
$params->getSite()->getId(),
$params->getSite()->getId(),
$params->getPeriod()->getDateStart()->toString(),
$params->getPeriod()->getDateEnd()->toString(),
$doneFlag
);
}
private function makeArchivingLockFromDoneFlag($idSite, $date1, $date2, $period, $doneFlag)
{
$lockKeyParts = [
self::LOCK_KEY_PREFIX,
$idSite,
// md5 to keep it within the 70 char limit in the table
md5($period . $date1 . ',' . $date2 . $doneFlag),
];
$lockKeyPrefix = implode('.', $lockKeyParts);
return new Lock(StaticContainer::get(LockBackend::class), $lockKeyPrefix, $this->archivingTTLSecs);
}
}
|