summaryrefslogtreecommitdiff
path: root/src/syncevo/SyncContext.cpp
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2013-04-24 12:00:45 +0200
committerPatrick Ohly <patrick.ohly@intel.com>2013-05-13 17:49:50 +0200
commit9a4c770d8e8b2ee5d8ac766faf7c7362fde3a82b (patch)
tree205e915497472c3d0a17d88e7d6d4244e547fd96 /src/syncevo/SyncContext.cpp
parent2032d17098fe3baab9eedb1272a2a27cce8a3608 (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.cpp44
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) {