Commit 677442d5 authored by Sebastian Kummer's avatar Sebastian Kummer

Merge pull request #216 in ZP/z-push from...

Merge pull request #216 in ZP/z-push from feature/ZP-837-have-a-configurable-sync_max_response_time to develop

* commit 'a88cd476':
  ZP-837 Fixed even more tpos.
  ZP-837 Fixed tpo!.
  ZP-837 Added config options do categorize devices, when exporting keep looking at the total runtime and stop in time.
parents 7f31028e a88cd476
......@@ -258,6 +258,20 @@
// The minimum accepted value is 1 second. The maximum accepted value is 3540 seconds (59 minutes).
define('PING_HIGHER_BOUND_LIFETIME', false);
// Maximum response time
// Mobiles implement different timeouts to their TCP/IP connections. Android devices for example
// have a hard timeout of 30 seconds. If the server is not able to answer a request within this timeframe,
// the answer will not be recieved and the device will send a new one overloading the server.
// There are three categories
// - Short timeout - server has up within 30 seconds - is automatically applied for not categorized types
// - Medium timeout - server has up to 90 seconds to respond
// - Long timeout - server has up to 4 minutes to respond
// If a timeout is almost reached the server will break and sent the results it has until this
// point. You can add DeviceType strings to the categories.
// In general longer timeouts are better, because more data can be streamed at once.
define('SYNC_TIMEOUT_MEDIUM_DEVICETYPES', "SAMSUNGGTI");
define('SYNC_TIMEOUT_LONG_DEVICETYPES', "iPod, iPad, iPhone, WP, WindowsOutlook");
/**********************************************************************************
* Backend settings
*/
......
......@@ -191,9 +191,7 @@ class FolderSync extends RequestProcessor {
$exporter->InitializeExporter($changesMem);
// Stream all changes to the ImportExportChangesMem
$maxExporttime = Request::GetExpectedConnectionTimeout();
$totalChanges = $exporter->GetChangeCount();
$started = time();
$exported = 0;
$partial = false;
while(is_array($exporter->Synchronize())) {
......@@ -204,8 +202,8 @@ class FolderSync extends RequestProcessor {
}
// if partial sync is allowed, stop if this takes too long
if (USE_PARTIAL_FOLDERSYNC && (time() - $started) > $maxExporttime) {
ZLog::Write(LOGLEVEL_WARN, sprintf("Request->HandleFolderSync(): Exporting folders is too slow. In %d seconds only %d from %d changes were processed.",(time() - $started), $exported, $totalChanges));
if (USE_PARTIAL_FOLDERSYNC && Request::IsRequestTimeoutReached()) {
ZLog::Write(LOGLEVEL_WARN, sprintf("Request->HandleFolderSync(): Exporting folders is too slow. In %d seconds only %d from %d changes were processed.",(time() - $_SERVER["REQUEST_TIME"]), $exported, $totalChanges));
self::$topCollector->AnnounceInformation(sprintf("Partial export of %d out of %d folders", $exported, $totalChanges), true);
self::$deviceManager->SetFolderSyncComplete(false);
$partial = true;
......
......@@ -97,7 +97,7 @@ class Request {
static private $koeVersion;
static private $koeBuild;
static private $koeBuildDate;
static private $expectedConnectionTimeout;
/**
* Initializes request data
......@@ -626,17 +626,32 @@ class Request {
// The amount of time returned is somehow lower than the max timeout so we have
// time for processing.
// Apple and Windows Phone have higher timeouts (4min = 240sec)
if (in_array(self::GetDeviceType(), array("iPod", "iPad", "iPhone", "WP"))) {
return 200;
}
// Samsung devices have a intermediate timeout (90sec)
if (in_array(self::GetDeviceType(), array("SAMSUNGGTI"))) {
return 50;
if (!isset(self::$expectedConnectionTimeout)) {
// Apple and Windows Phone have higher timeouts (4min = 240sec)
if (stripos(SYNC_TIMEOUT_LONG_DEVICETYPES, self::GetDeviceType()) !== false) {
self::$expectedConnectionTimeout = 210;
}
// Samsung devices have a intermediate timeout (90sec)
else if (stripos(SYNC_TIMEOUT_MEDIUM_DEVICETYPES, self::GetDeviceType()) !== false) {
self::$expectedConnectionTimeout = 85;
}
else {
// for all other devices, a timeout of 30 seconds is expected
self::$expectedConnectionTimeout = 28;
}
}
return self::$expectedConnectionTimeout;
}
// for all other devices, a timeout of 30 seconds is expected
return 20;
/**
* Indicates if the maximum timeout for the devicetype of this request is
* almost reached.
*
* @access public
* @return boolean
*/
static public function IsRequestTimeoutReached() {
return (time() - $_SERVER["REQUEST_TIME"]) >= self::GetExpectedConnectionTimeout();
}
/**----------------------------------------------------------------------------------------------------------
......
......@@ -782,6 +782,11 @@ class Sync extends RequestProcessor {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("Sync(): no exporter setup for '%s' as GlobalWindowSize is full.", $spa->GetFolderId()));
$setupExporter = false;
}
// if the maximum request timeout is reached, stop processing other collections
if (Request::IsRequestTimeoutReached()) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("Sync(): no exporter setup for '%s' as request timeout reached, omitting output for collection.", $spa->GetFolderId()));
$setupExporter = false;
}
// compare the folder statistics if the backend supports this
if ($setupExporter && self::$backend->HasFolderStats()) {
......@@ -1084,6 +1089,7 @@ class Sync extends RequestProcessor {
}
if($sc->GetParameter($spa, "getchanges") && $spa->HasFolderId() && $spa->HasContentClass() && $spa->HasSyncKey()) {
$moreAvailableSent = false;
$windowSize = self::$deviceManager->GetWindowSize($spa->GetFolderId(), $spa->GetUuid(), $spa->GetUuidCounter(), $changecount);
// limit windowSize to the max available limit of the global window size left
......@@ -1096,6 +1102,7 @@ class Sync extends RequestProcessor {
// or there is a move state (another sync should be done afterwards)
if($changecount > $windowSize || $spa->GetMoveState() !== false) {
self::$encoder->startTag(SYNC_MOREAVAILABLE, false, true);
$moreAvailableSent = true;
$spa->DelFolderStat();
}
}
......@@ -1141,7 +1148,7 @@ class Sync extends RequestProcessor {
}
}
if($n >= $windowSize) {
if($n >= $windowSize || Request::IsRequestTimeoutReached()) {
ZLog::Write(LOGLEVEL_DEBUG, sprintf("HandleSync(): Exported maxItems of messages: %d / %d", $n, $changecount));
break;
}
......@@ -1154,6 +1161,18 @@ class Sync extends RequestProcessor {
}
self::$encoder->endTag();
// log the request timeout
if (Request::IsRequestTimeoutReached()) {
ZLog::Write(LOGLEVEL_DEBUG, "HandleSync(): Stopping export as maximum request timeout is almost reached!");
// Send a <MoreAvailable/> tag if we reached the request timeout, there are more changes and a moreavailable was not already send
if (!$moreAvailableSent && ($n > $windowSize)) {
self::$encoder->startTag(SYNC_MOREAVAILABLE, false, true);
$spa->DelFolderStat();
$moreAvailableSent = true;
}
}
self::$topCollector->AnnounceInformation(sprintf("Outgoing %d objects%s", $n, ($n >= $windowSize)?" of ".$changecount:""), $this->singleFolder);
$this->saveMultiFolderInfo("outgoing", $n);
$this->saveMultiFolderInfo("queued", $changecount);
......
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