diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2013-04-24 12:00:45 +0200 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2013-05-13 17:49:50 +0200 |
commit | 9a4c770d8e8b2ee5d8ac766faf7c7362fde3a82b (patch) | |
tree | 205e915497472c3d0a17d88e7d6d4244e547fd96 /src/syncevo/SyncContext.cpp | |
parent | 2032d17098fe3baab9eedb1272a2a27cce8a3608 (diff) |
engine: prevent timeouts in HTTP server mode
HTTP SyncML clients give up after a certain timeout (SyncEvolution
after RetryDuration = 5 minutes by default, Nokia e51 after 15
minutes) when the server fails to respond.
This can happen with SyncEvolution as server when it uses a slow
storage with many items, for example via WebDAV. In the case of slow
session startup, multithreading is now used to run the storage
initializing in parallel to sending regular "keep-alive" SyncML
replies to the client.
By default, these replies are sent every 2 minutes. This can be
configured with another extensions of the SyncMLVersion property:
SyncMLVersion = REQUESTMAXTIME=5m
Other modes do not use multithreading by default, but it can be
enabled by setting REQUESTMAXTIME explicitly. It can be disabled
by setting the time to zero.
The new feature depends on a libsynthesis with multithreading enabled
and glib >= 2.32.0, which is necessary to make SyncEvolution itself
thread-safe. With an older glib, multithreading is disabled, but can
be enabled as a stop-gap measure by setting REQUESTMAXTIME explicitly.
Diffstat (limited to 'src/syncevo/SyncContext.cpp')
-rw-r--r-- | src/syncevo/SyncContext.cpp | 44 |
1 files changed, 42 insertions, 2 deletions
diff --git a/src/syncevo/SyncContext.cpp b/src/syncevo/SyncContext.cpp index 148f8c68..a2b2b338 100644 --- a/src/syncevo/SyncContext.cpp +++ b/src/syncevo/SyncContext.cpp @@ -27,6 +27,7 @@ #include <syncevo/SyncSource.h> #include <syncevo/util.h> #include <syncevo/SuspendFlags.h> +#include <syncevo/ThreadSupport.h> #include <syncevo/SafeConfigNode.h> #include <syncevo/IniConfigNode.h> @@ -2429,7 +2430,45 @@ void SyncContext::getConfigXML(string &xml, string &configname) " <server type='plugin'>\n" " <plugin_module>SyncEvolution</plugin_module>\n" " <plugin_sessionauth>yes</plugin_sessionauth>\n" - " <plugin_deviceadmin>yes</plugin_deviceadmin>\n" + " <plugin_deviceadmin>yes</plugin_deviceadmin>\n"; + + InitState<unsigned int> configrequestmaxtime = getRequestMaxTime(); + unsigned int requestmaxtime; + if (configrequestmaxtime.wasSet()) { + // Explicitly set, use it regardless of the kind of sync. + // We allow this even if thread support was not available, + // because if a user enables it explicitly, it's probably + // for a good reason (= failing client), in which case + // risking multithreading issues is preferable. + requestmaxtime = configrequestmaxtime.get(); + } else if (m_remoteInitiated || m_localSync) { + // We initiated the sync (local sync, Bluetooth). The client + // should not time out, so there is no need for intermediate + // message sending. + // + // To avoid potential problems and get a single log file, + // avoid it and multithreading by default. + requestmaxtime = 0; + } else { + // We were contacted by an HTTP client. Reply to client + // not later than 120 seconds while storage initializes + // in a background thread. +#ifdef HAVE_THREAD_SUPPORT + requestmaxtime = 120; // default in seconds +#else + requestmaxtime = 0; +#endif + } + if (requestmaxtime) { + clientorserver << + " <multithread>yes</multithread>\n" + " <requestmaxtime>" << requestmaxtime << "</requestmaxtime>\n"; + } else { + clientorserver << + " <multithread>no</multithread>\n"; + } + + clientorserver << "\n" << sessioninitscript << " <sessiontimeout>300</sessiontimeout>\n" @@ -2454,6 +2493,7 @@ void SyncContext::getConfigXML(string &xml, string &configname) clientorserver << " <client type='plugin'>\n" " <binfilespath>$(binfilepath)</binfilespath>\n" + " <multithread>no</multithread>\n" " <defaultauth/>\n"; if (getRefreshSync()) { clientorserver << @@ -2511,7 +2551,7 @@ void SyncContext::getConfigXML(string &xml, string &configname) " <timestamp>yes</timestamp>\n" " <timestampall>yes</timestampall>\n" " <timedsessionlognames>no</timedsessionlognames>\n" - " <subthreadmode>suppress</subthreadmode>\n" + " <subthreadmode>separate</subthreadmode>\n" " <logsessionstoglobal>yes</logsessionstoglobal>\n" " <singlegloballog>yes</singlegloballog>\n"; if (logging) { |