Commit 8e3339da authored by Sebastian Kummer's avatar Sebastian Kummer

ZP-851 Added an expiration time for folder stats depending on the

filtertype (max. 1 month) that is taken into account when calling sync
and in ping to determine if an exporter run is required on a folder.

Released under the Affero GNU General Public License (AGPL) version 3.
parent 17813d04
......@@ -518,7 +518,7 @@ class SyncCollections implements Iterator {
}
// check if the folder stat changed since the last sync, if so generate a change for it (only on first run)
if ($this->waitingTime == 0 && ZPush::GetBackend()->HasFolderStats() && $spa->HasFolderStat() && ZPush::GetBackend()->GetFolderStat($store, $spa->GetFolderId()) !== $spa->GetFolderStat()) {
if ($this->waitingTime == 0 && ZPush::GetBackend()->HasFolderStats() && $spa->IsExporterRunRequired(ZPush::GetBackend()->GetFolderStat($store, $spa->GetFolderId()), true)) {
$this->changes[$spa->GetFolderId()] = 1;
}
}
......
......@@ -72,6 +72,7 @@ class SyncParameters extends StateObject {
'foldersynctotal' => false,
'foldersyncremaining' => false,
'folderstat' => false,
'folderstattimeout' => false,
);
/**
......@@ -275,6 +276,25 @@ class SyncParameters extends StateObject {
$this->checkCPO($this->currentCPO);
}
/**
* Indicates if a exporter run is required. This is the case if the given folderstat is different form the saved one
* or when the expiration time expired.
*
* @param string $currentFolderStat
* @param boolean $doLog
*
* @access public
* @return boolean
*/
public function IsExporterRunRequired($currentFolderStat, $doLog = false) {
$run = ! ($this->HasFolderStat() && $currentFolderStat === $this->GetFolderStat() && time() < $this->GetFolderStatTimeout());
if ($doLog) {
$expDate = ($this->HasFolderStatTimeout()) ? date('Y-m-d H:i:s', $this->GetFolderStatTimeout()) : "not set";
ZLog::Write(LOGLEVEL_DEBUG, sprintf("SyncParameters->IsExporterRunRequired(): %s - current: %s - saved: %s - expiring: %s", Utils::PrintAsString($run), $currentFolderStat, Utils::PrintAsString($this->GetFolderStat()), $expDate));
}
return $run;
}
/**
* Checks if a CPO is correctly inicialized and inicializes it if necessary
*
......
......@@ -741,7 +741,7 @@ class Sync extends RequestProcessor {
if ($setupExporter && self::$backend->HasFolderStats()) {
// check if the folder stats changed -> if not, don't setup the exporter, there are no changes!
$newFolderStat = self::$backend->GetFolderStat(ZPush::GetAdditionalSyncFolderStore($spa->GetFolderId()), $spa->GetFolderId());
if ($spa->HasFolderStat() && $newFolderStat === $spa->GetFolderStat()) {
if (! $spa->IsExporterRunRequired($newFolderStat, true)) {
$changecount = 0;
$setupExporter = false;
ZLog::Write(LOGLEVEL_DEBUG, "Sync(): Folder stat from the backend indicates that the folder did not change. Exporter will not run.");
......@@ -828,7 +828,7 @@ class Sync extends RequestProcessor {
// Fir AS 14.0+ omit output for folder, if there were no incoming or outgoing changes and no Fetch
if (Request::GetProtocolVersion() >= 14.0 && ! $spa->HasNewSyncKey() && $changecount == 0 && empty($actiondata["fetchids"]) && $status == SYNC_STATUS_SUCCESS &&
$spa->HasFolderStat() && $spa->GetFolderStat() === $newFolderStat) {
! $spa->IsExporterRunRequired($newFolderStat)) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync: No changes found for %s folder id '%s'. Omitting output.", $spa->GetContentClass(), $spa->GetFolderId()));
continue;
}
......@@ -1118,7 +1118,7 @@ class Sync extends RequestProcessor {
// changecount is initialized with 'false', so 0 means no changes!
if ($changecount === 0 || ($changecount !== false && $changecount <= $windowSize)) {
self::$deviceManager->SetFolderSyncStatus($spa->GetFolderId(), DeviceManager::FLD_SYNC_COMPLETED);
$spa->SetFolderStat($newFolderStat);
$this->setFolderStat($spa, $newFolderStat);
}
else
self::$deviceManager->SetFolderSyncStatus($spa->GetFolderId(), DeviceManager::FLD_SYNC_INPROGRESS);
......@@ -1468,4 +1468,23 @@ class Sync extends RequestProcessor {
}
return $s;
}
/**
* Sets the new folderstat and calculates & sets an expiration date for the folder stat.
*
* @param SyncParameters $spa
* @param string $newFolderStat
*
* @access private
* @return
*/
private function setFolderStat($spa, $newFolderStat) {
$spa->SetFolderStat($newFolderStat);
$maxTimeout = 60 * 60 * 24 * 31; // one month
$interval = Utils::GetFiltertypeInterval($spa->GetFilterType());
$timeout = time() + (($interval && $interval < $maxTimeout) ? $interval : $maxTimeout);
ZLog::Write(LOGLEVEL_DEBUG, sprintf("Sync()->setFolderStat() on %s: %s expiring %s", $spa->getFolderId(), $newFolderStat, date('Y-m-d H:i:s', $timeout)));
$spa->SetFolderStatTimeout($timeout);
}
}
......@@ -308,13 +308,32 @@ class Utils {
/**
* Converts SYNC_FILTERTYPE into a timestamp
*
* @param int Filtertype
* @param int $filtertype Filtertype
*
* @access public
* @return long
*/
static public function GetCutOffDate($restrict) {
switch($restrict) {
static public function GetCutOffDate($filtertype) {
$back = Utils::GetFiltertypeInterval($filtertype);
if ($back === false) {
return 0; // unlimited
}
return time() - $back;
}
/**
* Returns the interval indicated by the filtertype.
*
* @param int $filtertype
*
* @access public
* @return long|boolean returns false on invalid filtertype
*/
static public function GetFiltertypeInterval($filtertype) {
$back = false;
switch($filtertype) {
case SYNC_FILTERTYPE_1DAY:
$back = 60 * 60 * 24;
break;
......@@ -337,10 +356,9 @@ class Utils {
$back = 60 * 60 * 24 * 31 * 6;
break;
default:
return 0; // unlimited
$back = false;
}
return time() - $back;
return $back;
}
/**
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment