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 { ...@@ -45,6 +45,9 @@ class Sync extends RequestProcessor {
// Ignored SMS identifier // Ignored SMS identifier
const ZPUSHIGNORESMS = "ZPISMS"; const ZPUSHIGNORESMS = "ZPISMS";
private $importer; private $importer;
private $globallyExportedItems;
private $startTagsSent = false;
private $startFolderTagSent = false;
/** /**
* Handles the Sync command * Handles the Sync command
...@@ -61,7 +64,7 @@ class Sync extends RequestProcessor { ...@@ -61,7 +64,7 @@ class Sync extends RequestProcessor {
$status = SYNC_STATUS_SUCCESS; $status = SYNC_STATUS_SUCCESS;
$wbxmlproblem = false; $wbxmlproblem = false;
$emptysync = false; $emptysync = false;
$globallyExportedItems = 0; $this->globallyExportedItems = 0;
// check if the hierarchySync was fully completed // check if the hierarchySync was fully completed
...@@ -662,22 +665,20 @@ class Sync extends RequestProcessor { ...@@ -662,22 +665,20 @@ class Sync extends RequestProcessor {
} }
} }
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync(): Start Output"));
// Start the output // Start the output
self::$encoder->startWBXML(); ZLog::Write(LOGLEVEL_DEBUG, "HandleSync(): Start Output");
self::$encoder->startTag(SYNC_SYNCHRONIZE);
{
// global status // global status
// SYNC_COMMONSTATUS_* start with values from 101 // SYNC_COMMONSTATUS_* start with values from 101
if ($status != SYNC_COMMONSTATUS_SUCCESS && $status > 100) { if ($status != SYNC_COMMONSTATUS_SUCCESS && $status > 100) {
$this->sendStartTags();
self::$encoder->startTag(SYNC_STATUS); self::$encoder->startTag(SYNC_STATUS);
self::$encoder->content($status); self::$encoder->content($status);
self::$encoder->endTag(); self::$encoder->endTag();
return true;
} }
else {
self::$encoder->startTag(SYNC_FOLDERS); // Loop through requested folders
{
foreach($sc as $folderid => $spa) { foreach($sc as $folderid => $spa) {
// get actiondata // get actiondata
$actiondata = $sc->GetParameter($spa, "actiondata"); $actiondata = $sc->GetParameter($spa, "actiondata");
...@@ -692,8 +693,8 @@ class Sync extends RequestProcessor { ...@@ -692,8 +693,8 @@ class Sync extends RequestProcessor {
// initialize exporter to get changecount // initialize exporter to get changecount
$changecount = false; $changecount = false;
if (isset($exporter)) $exporter = false;
unset($exporter); $streamimporter = false;
// TODO we could check against $sc->GetChangedFolderIds() on heartbeat so we do not need to configure all exporter again // 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())) { if($status == SYNC_STATUS_SUCCESS && ($sc->GetParameter($spa, "getchanges") || ! $spa->HasSyncKey())) {
...@@ -750,11 +751,6 @@ class Sync extends RequestProcessor { ...@@ -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 // 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"]) || if (!empty($actiondata["modifyids"]) ||
!empty($actiondata["clientids"]) || !empty($actiondata["clientids"]) ||
...@@ -765,7 +761,7 @@ class Sync extends RequestProcessor { ...@@ -765,7 +761,7 @@ class Sync extends RequestProcessor {
// get a new synckey only if we did not reach the global limit yet // get a new synckey only if we did not reach the global limit yet
else { else {
// when reaching the global limit for changes of all collections, stop processing other collections (ZP-697) // 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."); ZLog::Write(LOGLEVEL_DEBUG, "Global WindowSize for amount of exported changes reached, omitting output for collection.");
continue; continue;
} }
...@@ -776,6 +772,75 @@ class Sync extends RequestProcessor { ...@@ -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); self::$encoder->startTag(SYNC_FOLDER);
if($spa->HasContentClass()) { if($spa->HasContentClass()) {
...@@ -910,7 +975,7 @@ class Sync extends RequestProcessor { ...@@ -910,7 +975,7 @@ class Sync extends RequestProcessor {
$windowSize = self::$deviceManager->GetWindowSize($spa->GetFolderId(), $spa->GetContentClass(), $spa->GetUuid(), $spa->GetUuidCounter(), $changecount); $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 // 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) { 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)); ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync(): Limit window size to %d as the global window size limit will be reached", $globallyAvailable));
$windowSize = $globallyAvailable; $windowSize = $globallyAvailable;
...@@ -922,7 +987,7 @@ class Sync extends RequestProcessor { ...@@ -922,7 +987,7 @@ class Sync extends RequestProcessor {
} }
// Stream outgoing changes // 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))); self::$topCollector->AnnounceInformation(sprintf("Streaming data of %d objects", (($changecount > $windowSize)?$windowSize:$changecount)));
// Output message changes per folder // Output message changes per folder
...@@ -969,14 +1034,14 @@ class Sync extends RequestProcessor { ...@@ -969,14 +1034,14 @@ class Sync extends RequestProcessor {
} }
// $progress is not an array when exporting the last message // $progress is not an array when exporting the last message
// so we get the number to display from the streamimporter // so we get the number to display from the streamimporter if it's available
if (isset($streamimporter)) { if (!!$streamimporter) {
$n = $streamimporter->GetImportedMessages(); $n = $streamimporter->GetImportedMessages();
} }
self::$encoder->endTag(); self::$encoder->endTag();
self::$topCollector->AnnounceInformation(sprintf("Outgoing %d objects%s", $n, ($n >= $windowSize)?" of ".$changecount:""), true); 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 // update folder status, if there is something set
if ($spa->GetFolderSyncRemaining() && $changecount > 0) { if ($spa->GetFolderSyncRemaining() && $changecount > 0) {
...@@ -984,9 +1049,9 @@ class Sync extends RequestProcessor { ...@@ -984,9 +1049,9 @@ class Sync extends RequestProcessor {
} }
// changecount is initialized with 'false', so 0 means no changes! // changecount is initialized with 'false', so 0 means no changes!
if ($changecount === 0 || ($changecount !== false && $changecount <= $windowSize)) 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 else
self::$deviceManager->SetFolderSyncStatus($folderid, DeviceManager::FLD_SYNC_INPROGRESS); self::$deviceManager->SetFolderSyncStatus($spa->GetFolderId(), DeviceManager::FLD_SYNC_INPROGRESS);
} }
self::$encoder->endTag(); self::$encoder->endTag();
...@@ -1022,18 +1087,7 @@ class Sync extends RequestProcessor { ...@@ -1022,18 +1087,7 @@ class Sync extends RequestProcessor {
if ($status == SYNC_STATUS_SUCCESS && empty($actiondata["fetchids"])) if ($status == SYNC_STATUS_SUCCESS && empty($actiondata["fetchids"]))
$sc->SaveCollection($spa); $sc->SaveCollection($spa);
// reset status for the next folder return $status;
$status = SYNC_STATUS_SUCCESS;
} // END foreach collection
}
self::$encoder->endTag(); //SYNC_FOLDERS
}
}
self::$encoder->endTag(); //SYNC_SYNCHRONIZE
return true;
} }
/** /**
......
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