Commit 5e0e469d authored by Sebastian Kummer's avatar Sebastian Kummer

Merge branch 'feature/ZP-818-send-no-answer-collection-for-unchanged' into...

Merge branch 'feature/ZP-818-send-no-answer-collection-for-unchanged' into feature/ZP-832-detect-folder-changes-faster
parents f9e71d7f 5179ec79
......@@ -45,6 +45,9 @@ class Sync extends RequestProcessor {
// Ignored SMS identifier
const ZPUSHIGNORESMS = "ZPISMS";
private $importer;
private $globallyExportedItems;
private $startTagsSent = false;
private $startFolderTagSent = false;
/**
* Handles the Sync command
......@@ -61,7 +64,7 @@ class Sync extends RequestProcessor {
$status = SYNC_STATUS_SUCCESS;
$wbxmlproblem = false;
$emptysync = false;
$globallyExportedItems = 0;
$this->globallyExportedItems = 0;
// check if the hierarchySync was fully completed
......@@ -662,22 +665,20 @@ class Sync extends RequestProcessor {
}
}
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync(): Start Output"));
// Start the output
self::$encoder->startWBXML();
self::$encoder->startTag(SYNC_SYNCHRONIZE);
{
ZLog::Write(LOGLEVEL_DEBUG, "HandleSync(): Start Output");
// global status
// SYNC_COMMONSTATUS_* start with values from 101
if ($status != SYNC_COMMONSTATUS_SUCCESS && $status > 100) {
$this->sendStartTags();
self::$encoder->startTag(SYNC_STATUS);
self::$encoder->content($status);
self::$encoder->endTag();
return true;
}
else {
self::$encoder->startTag(SYNC_FOLDERS);
{
// Loop through requested folders
foreach($sc as $folderid => $spa) {
// get actiondata
$actiondata = $sc->GetParameter($spa, "actiondata");
......@@ -692,8 +693,8 @@ class Sync extends RequestProcessor {
// initialize exporter to get changecount
$changecount = false;
if (isset($exporter))
unset($exporter);
$exporter = false;
$streamimporter = false;
// TODO we could check against $sc->GetChangedFolderIds() on heartbeat so we do not need to configure all exporter again
if($status == SYNC_STATUS_SUCCESS && ($sc->GetParameter($spa, "getchanges") || ! $spa->HasSyncKey())) {
......@@ -750,11 +751,6 @@ class Sync extends RequestProcessor {
}
}
if (isset($hbinterval) && $changecount == 0 && $status == SYNC_STATUS_SUCCESS) {
ZLog::Write(LOGLEVEL_DEBUG, "No changes found for heartbeat folder. Omitting empty output.");
continue;
}
// Get a new sync key to output to the client if any changes have been send by the mobile or a new synckey is to be sent
if (!empty($actiondata["modifyids"]) ||
!empty($actiondata["clientids"]) ||
......@@ -765,7 +761,7 @@ class Sync extends RequestProcessor {
// get a new synckey only if we did not reach the global limit yet
else {
// when reaching the global limit for changes of all collections, stop processing other collections (ZP-697)
if ($sc->GetGlobalWindowSize() <= $globallyExportedItems) {
if ($sc->GetGlobalWindowSize() <= $this->globallyExportedItems) {
ZLog::Write(LOGLEVEL_DEBUG, "Global WindowSize for amount of exported changes reached, omitting output for collection.");
continue;
}
......@@ -776,6 +772,75 @@ 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) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync: No changes found for %s folder id '%s'. Omitting output.", $spa->GetContentClass(), $spa->GetFolderId()));
continue;
}
// there is something to send here, sync folder to output
$this->syncFolder($sc, $spa, $exporter, $changecount, $streamimporter, $status);
// reset status for the next folder
$status = SYNC_STATUS_SUCCESS;
} // END foreach collection
//SYNC_FOLDERS - only if the starttag was sent
if ($this->startFolderTagSent)
self::$encoder->endTag();
//SYNC_SYNCHRONIZE - only if the starttag was sent
if ($this->startTagsSent)
self::$encoder->endTag();
return true;
}
/**
* Sends the SYNC_SYNCHRONIZE once per request.
*
* @access private
* @return void
*/
private function sendStartTags() {
if ($this->startTagsSent === false) {
self::$encoder->startWBXML();
self::$encoder->startTag(SYNC_SYNCHRONIZE);
$this->startTagsSent = true;
}
}
/**
* Sends the SYNC_FOLDERS once per request.
*
* @access private
* @return void
*/
private function sendFolderStartTag() {
$this->sendStartTags();
if ($this->startFolderTagSent === false) {
self::$encoder->startTag(SYNC_FOLDERS);
$this->startFolderTagSent = true;
}
}
/**
* Synchronizes a folder to the output stream. Changes for this folders are expected.
*
* @param SyncCollections $sc
* @param SyncParameters $spa
* @param IExportChanges $exporter Fully configured exporter for this folder
* @param int $changecount Amount of changes expected
* @param ImportChangesStream $streamimporter Output stream
* @param int $status current status of the folder processing
* @throws StatusException
* @return int sync status code
*/
private function syncFolder($sc, $spa, $exporter, $changecount, $streamimporter, $status) {
$actiondata = $sc->GetParameter($spa, "actiondata");
// send the WBXML start tags (if not happened already)
$this->sendFolderStartTag();
self::$encoder->startTag(SYNC_FOLDER);
if($spa->HasContentClass()) {
......@@ -910,7 +975,7 @@ class Sync extends RequestProcessor {
$windowSize = self::$deviceManager->GetWindowSize($spa->GetFolderId(), $spa->GetContentClass(), $spa->GetUuid(), $spa->GetUuidCounter(), $changecount);
// limit windowSize to the max available limit of the global window size left
$globallyAvailable = $sc->GetGlobalWindowSize() - $globallyExportedItems;
$globallyAvailable = $sc->GetGlobalWindowSize() - $this->globallyExportedItems;
if ($changecount > $globallyAvailable && $windowSize > $globallyAvailable) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync(): Limit window size to %d as the global window size limit will be reached", $globallyAvailable));
$windowSize = $globallyAvailable;
......@@ -922,7 +987,7 @@ class Sync extends RequestProcessor {
}
// Stream outgoing changes
if($status == SYNC_STATUS_SUCCESS && $sc->GetParameter($spa, "getchanges") == true && $windowSize > 0) {
if($status == SYNC_STATUS_SUCCESS && $sc->GetParameter($spa, "getchanges") == true && $windowSize > 0 && !!$exporter) {
self::$topCollector->AnnounceInformation(sprintf("Streaming data of %d objects", (($changecount > $windowSize)?$windowSize:$changecount)));
// Output message changes per folder
......@@ -969,14 +1034,14 @@ class Sync extends RequestProcessor {
}
// $progress is not an array when exporting the last message
// so we get the number to display from the streamimporter
if (isset($streamimporter)) {
// so we get the number to display from the streamimporter if it's available
if (!!$streamimporter) {
$n = $streamimporter->GetImportedMessages();
}
self::$encoder->endTag();
self::$topCollector->AnnounceInformation(sprintf("Outgoing %d objects%s", $n, ($n >= $windowSize)?" of ".$changecount:""), true);
$globallyExportedItems += $n;
$this->globallyExportedItems += $n;
// update folder status, if there is something set
if ($spa->GetFolderSyncRemaining() && $changecount > 0) {
......@@ -984,9 +1049,9 @@ class Sync extends RequestProcessor {
}
// changecount is initialized with 'false', so 0 means no changes!
if ($changecount === 0 || ($changecount !== false && $changecount <= $windowSize))
self::$deviceManager->SetFolderSyncStatus($folderid, DeviceManager::FLD_SYNC_COMPLETED);
self::$deviceManager->SetFolderSyncStatus($spa->GetFolderId(), DeviceManager::FLD_SYNC_COMPLETED);
else
self::$deviceManager->SetFolderSyncStatus($folderid, DeviceManager::FLD_SYNC_INPROGRESS);
self::$deviceManager->SetFolderSyncStatus($spa->GetFolderId(), DeviceManager::FLD_SYNC_INPROGRESS);
}
self::$encoder->endTag();
......@@ -1022,18 +1087,7 @@ class Sync extends RequestProcessor {
if ($status == SYNC_STATUS_SUCCESS && empty($actiondata["fetchids"]))
$sc->SaveCollection($spa);
// reset status for the next folder
$status = SYNC_STATUS_SUCCESS;
} // END foreach collection
}
self::$encoder->endTag(); //SYNC_FOLDERS
}
}
self::$encoder->endTag(); //SYNC_SYNCHRONIZE
return true;
return $status;
}
/**
......
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