diff --git a/core/Archive.php b/core/Archive.php index dcc14b7ad0990082336c2c698df7bdd14c97e3fd..eada3e2b531d5f23fbf5d18bfa8a7ba14e5d5bb7 100644 --- a/core/Archive.php +++ b/core/Archive.php @@ -486,19 +486,43 @@ class Archive return $recordName . "_" . $id; } - private function invalidatedReportsIfNeeded() + private function getSiteIdsThatAreRequestedInThisArchiveButWereNotInvalidatedYet() { if (is_null(self::$cache)) { self::$cache = Cache::getTransientCache(); } - $id = 'Archive.RememberedReportsInvalidated'; + $id = 'Archive.SiteIdsOfRememberedReportsInvalidated'; - if (self::$cache->contains($id)) { - return; + if (!self::$cache->contains($id)) { + self::$cache->save($id, array()); } - self::$cache->save($id, 1); + $siteIdsAlreadyHandled = self::$cache->fetch($id); + $siteIdsRequested = $this->params->getIdSites(); + + foreach ($siteIdsRequested as $index => $siteIdRequested) { + $siteIdRequested = (int) $siteIdRequested; + + if (in_array($siteIdRequested, $siteIdsAlreadyHandled)) { + unset($siteIdsRequested[$index]); // was already handled previously, do not do it again + } else { + $siteIdsAlreadyHandled[] = $siteIdRequested; // we will handle this id this time + } + } + + self::$cache->save($id, $siteIdsAlreadyHandled); + + return $siteIdsRequested; + } + + private function invalidatedReportsIfNeeded() + { + $siteIdsRequested = $this->getSiteIdsThatAreRequestedInThisArchiveButWereNotInvalidatedYet(); + + if (empty($siteIdsRequested)) { + return; // all requested site ids were already handled + } $invalidator = new ArchiveInvalidator(); $sitesPerDays = $invalidator->getRememberedArchivedReportsThatShouldBeInvalidated(); @@ -508,10 +532,14 @@ class Archive continue; } + $siteIdsToActuallyInvalidate = array_intersect($siteIds, $siteIdsRequested); + + if (empty($siteIdsToActuallyInvalidate)) { + continue; // all site ids that should be handled are already handled + } + try { - // an advanced version would only invalidate siteIds for $this->params->getIdSites() but would make - // everything way more complex eg the cache above and which siteIds we pass here... - $invalidator->markArchivesAsInvalidated($siteIds, $date, false); + $invalidator->markArchivesAsInvalidated($siteIdsToActuallyInvalidate, $date, false); } catch (\Exception $e) { Site::clearCache(); throw $e; diff --git a/tests/PHPUnit/System/TwoVisitorsTwoWebsitesDifferentDaysConversionsTest.php b/tests/PHPUnit/System/TwoVisitorsTwoWebsitesDifferentDaysConversionsTest.php index 8542e5377480375735391a4af7cc0758879bfb71..712608c62e04cf85be2e6a5a194f297c15ddb443 100755 --- a/tests/PHPUnit/System/TwoVisitorsTwoWebsitesDifferentDaysConversionsTest.php +++ b/tests/PHPUnit/System/TwoVisitorsTwoWebsitesDifferentDaysConversionsTest.php @@ -163,13 +163,14 @@ class TwoVisitorsTwoWebsitesDifferentDaysConversionsTest extends SystemTestCase ); $cache = Cache::getTransientCache(); - $this->assertTrue($cache->contains('Archive.RememberedReportsInvalidated')); + $this->assertEquals(array(self::$fixture->idSite1, self::$fixture->idSite2), + $cache->fetch('Archive.SiteIdsOfRememberedReportsInvalidated')); $invalidator = new ArchiveInvalidator(); self::$fixture->trackVisits(); - // trackVisits should remember archived reports as invalid + // trackVisits should remember to invalidate archived reports $this->assertNotEmpty($invalidator->getRememberedArchivedReportsThatShouldBeInvalidated()); // although there were new tracked visists it doesn'T change as the report invalidation is cached and was @@ -186,16 +187,17 @@ class TwoVisitorsTwoWebsitesDifferentDaysConversionsTest extends SystemTestCase ); // make sure the caching in archive::get() worked and they are still to be invalidated - $this->assertNotEmpty($invalidator->getRememberedArchivedReportsThatShouldBeInvalidated()); + $this->assertCount(10, $invalidator->getRememberedArchivedReportsThatShouldBeInvalidated()); - // now we force to actually invalidate archived reports again and then archive will be rebuilt - $cache->delete('Archive.RememberedReportsInvalidated'); + // now we force to actually invalidate archived reports again and then archive will be rebuilt for requsted siteId = 1 + $cache->delete('Archive.SiteIdsOfRememberedReportsInvalidated'); $archive = Archive::build($idSite1, 'range', $dateTimeRange); $result = $archive->getNumeric($columns); - // archive::get() should have invalidated them now as we cleared the lock / cache before - $this->assertEmpty($invalidator->getRememberedArchivedReportsThatShouldBeInvalidated()); + // archive::get() should have invalidated siteId 1 and siteId 2 should be still to be done + $expectedArchiveReportsLeft = array('2010-01-04' => array(2)); + $this->assertEquals($expectedArchiveReportsLeft, $invalidator->getRememberedArchivedReportsThatShouldBeInvalidated()); $this->assertEquals( array(