Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattab <matthieu.aubry@gmail.com>2014-03-26 05:52:16 +0400
committermattab <matthieu.aubry@gmail.com>2014-03-26 05:52:16 +0400
commitaaafe466fc3634fb761697f95e3cefefba2b6a3f (patch)
tree7121fc357e1bae96a5df191c00a11eb557916cc2 /core/CronArchive
parent5575251dc27ad7877af6f2a2849619841ba9814d (diff)
Move two classes to another namespace
Diffstat (limited to 'core/CronArchive')
-rw-r--r--core/CronArchive/FixedSiteIds.php63
-rw-r--r--core/CronArchive/SharedSiteIds.php171
2 files changed, 234 insertions, 0 deletions
diff --git a/core/CronArchive/FixedSiteIds.php b/core/CronArchive/FixedSiteIds.php
new file mode 100644
index 0000000000..d79ce59461
--- /dev/null
+++ b/core/CronArchive/FixedSiteIds.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\CronArchive;
+
+use Piwik\CronArchive;
+
+class FixedSiteIds
+{
+ private $siteIds = array();
+ private $index = -1;
+
+ public function __construct($websiteIds)
+ {
+ if (!empty($websiteIds)) {
+ $this->siteIds = $websiteIds;
+ }
+ }
+
+ /**
+ * Get the number of total websites that needs to be processed.
+ *
+ * @return int
+ */
+ public function getNumSites()
+ {
+ return count($this->siteIds);
+ }
+
+ /**
+ * Get the number of already processed websites. All websites were processed by the current archiver.
+ *
+ * @return int
+ */
+ public function getNumProcessedWebsites()
+ {
+ $numProcessed = $this->index + 1;
+
+ if ($numProcessed > $this->getNumSites()) {
+ return $this->getNumSites();
+ }
+
+ return $numProcessed;
+ }
+
+ public function getNextSiteId()
+ {
+ $this->index++;
+
+ if (!empty($this->siteIds[$this->index])) {
+ return $this->siteIds[$this->index];
+ }
+
+ return null;
+ }
+
+}
+
diff --git a/core/CronArchive/SharedSiteIds.php b/core/CronArchive/SharedSiteIds.php
new file mode 100644
index 0000000000..8912b7d85f
--- /dev/null
+++ b/core/CronArchive/SharedSiteIds.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\CronArchive;
+
+use Exception;
+use Piwik\CliMulti\Process;
+use Piwik\Option;
+
+/**
+ * This class saves all to be processed siteIds in an Option named 'SharedSiteIdsToArchive' and processes all sites
+ * within that list. If a user starts multiple archiver those archiver will help to finish processing that list.
+ */
+class SharedSiteIds
+{
+ private $siteIds = array();
+ private $currentSiteId;
+ private $done = false;
+
+ public function __construct($websiteIds)
+ {
+ if (empty($websiteIds)) {
+ $websiteIds = array();
+ }
+
+ $self = $this;
+ $this->siteIds = $this->runExclusive(function () use ($self, $websiteIds) {
+ // if there are already sites to be archived registered, prefer the list of existing archive, meaning help
+ // to finish this queue of sites instead of starting a new queue
+ $existingWebsiteIds = $self->getAllSiteIdsToArchive();
+
+ if (!empty($existingWebsiteIds)) {
+ return $existingWebsiteIds;
+ }
+
+ $self->setSiteIdsToArchive($websiteIds);
+
+ return $websiteIds;
+ });
+ }
+
+ /**
+ * Get the number of total websites that needs to be processed.
+ *
+ * @return int
+ */
+ public function getNumSites()
+ {
+ return count($this->siteIds);
+ }
+
+ /**
+ * Get the number of already processed websites (not necessarily all of those where processed by this archiver).
+ *
+ * @return int
+ */
+ public function getNumProcessedWebsites()
+ {
+ if ($this->done) {
+ return $this->getNumSites();
+ }
+
+ if (empty($this->currentSiteId)) {
+ return 0;
+ }
+
+ $index = array_search($this->currentSiteId, $this->siteIds);
+
+ if (false === $index) {
+ return 0;
+ }
+
+ return $index + 1;
+ }
+
+ public function setSiteIdsToArchive($siteIds)
+ {
+ if (!empty($siteIds)) {
+ Option::set('SharedSiteIdsToArchive', implode(',', $siteIds));
+ } else {
+ Option::delete('SharedSiteIdsToArchive');
+ }
+ }
+
+ public function getAllSiteIdsToArchive()
+ {
+ Option::clearCachedOption('SharedSiteIdsToArchive');
+ $siteIdsToArchive = Option::get('SharedSiteIdsToArchive');
+
+ if (empty($siteIdsToArchive)) {
+ return array();
+ }
+
+ return explode(',', trim($siteIdsToArchive));
+ }
+
+ /**
+ * If there are multiple archiver running on the same node it makes sure only one of them performs an action and it
+ * will wait until another one has finished. Any closure you pass here should be very fast as other processes wait
+ * for this closure to finish otherwise. Currently only used for making multiple archivers at the same time work.
+ * If a closure takes more than 5 seconds we assume it is dead and simply continue.
+ *
+ * @param \Closure $closure
+ * @return mixed
+ * @throws \Exception
+ */
+ private function runExclusive($closure)
+ {
+ $process = new Process('archive.sharedsiteids');
+
+ while ($process->isRunning() && $process->getSecondsSinceCreation() < 5) {
+ // wait max 5 seconds, such an operation should not take longer
+ usleep(25 * 1000);
+ }
+
+ $process->startProcess();
+
+ try {
+ $result = $closure();
+ } catch (Exception $e) {
+ $process->finishProcess();
+ throw $e;
+ }
+
+ $process->finishProcess();
+
+ return $result;
+ }
+
+ /**
+ * Get the next site id that needs to be processed or null if all site ids where processed.
+ *
+ * @return int|null
+ */
+ public function getNextSiteId()
+ {
+ $self = $this;
+
+ $this->currentSiteId = $this->runExclusive(function () use ($self) {
+
+ $siteIds = $self->getAllSiteIdsToArchive();
+
+ if (empty($siteIds)) {
+ return null;
+ }
+
+ $nextSiteId = array_shift($siteIds);
+ $self->setSiteIdsToArchive($siteIds);
+
+ return $nextSiteId;
+ });
+
+ if (is_null($this->currentSiteId)) {
+ $this->done = true;
+ }
+
+ return $this->currentSiteId;
+ }
+
+ public static function isSupported()
+ {
+ return Process::isSupported();
+ }
+
+}
+