diff options
author | Patrick Ohly <patrick.ohly@intel.com> | 2013-04-02 07:36:21 -0700 |
---|---|---|
committer | Patrick Ohly <patrick.ohly@intel.com> | 2013-05-06 16:28:12 +0200 |
commit | e3f0a297f7a6799b8f4481b5142e78981ecef4a0 (patch) | |
tree | c724f26a7230a9a6fc29263595eb4dd86eacf650 | |
parent | 065fdcd34382a8bd4537a0f70c9a8b90c67d1bef (diff) |
EDS Client: handle "busy" error
In EDS 3.6.4, opening fails a lot more often with E_CLIENT_ERROR_BUSY.
We must retry until we succeed.
Seen in particular with testpim.py testFilterStartup. Clients are expected to
try the open call again. EDS >= 3.8 does that automatically.
-rw-r--r-- | src/backends/evolution/EvolutionSyncSource.cpp | 26 | ||||
-rw-r--r-- | src/dbus/server/pim/edsf-view.cpp | 57 |
2 files changed, 57 insertions, 26 deletions
diff --git a/src/backends/evolution/EvolutionSyncSource.cpp b/src/backends/evolution/EvolutionSyncSource.cpp index c22d3e93..d94a4448 100644 --- a/src/backends/evolution/EvolutionSyncSource.cpp +++ b/src/backends/evolution/EvolutionSyncSource.cpp @@ -89,19 +89,25 @@ EClientCXX EvolutionSyncSource::openESource(const char *extension, (void *)"Evolution Data Server has died unexpectedly."); - // Always allow EDS to create the database. "only-if-exists = - // true" does not make sense. - if (!e_client_open_sync(client, false, NULL, gerror)) { - if (created) { - // Opening newly created address books often failed in old - // EDS releases - try again. - gerror.clear(); - sleep(5); - if (!e_client_open_sync(client, false, NULL, gerror)) { + while (true) { + // Always allow EDS to create the database. "only-if-exists = + // true" does not make sense. + if (!e_client_open_sync(client, false, NULL, gerror)) { + if (gerror && g_error_matches(gerror, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) { + gerror.clear(); + sleep(1); + } else if (created) { + // Opening newly created address books often failed in + // old EDS releases - try again. Probably covered by + // more recently added E_CLIENT_ERROR_BUSY check above. + gerror.clear(); + sleep(5); + } else { throwError("opening database", gerror); } } else { - throwError("opening database", gerror); + // Success! + break; } } diff --git a/src/dbus/server/pim/edsf-view.cpp b/src/dbus/server/pim/edsf-view.cpp index eb869a7c..16972f33 100644 --- a/src/dbus/server/pim/edsf-view.cpp +++ b/src/dbus/server/pim/edsf-view.cpp @@ -49,6 +49,8 @@ boost::shared_ptr<EDSFView> EDSFView::create(const ESourceRegistryCXX ®istry, void EDSFView::doStart() { + // This function may get entered again, see retry code in opened() below. + ESourceCXX source(e_source_registry_ref_source(m_registry, m_uuid.c_str()), false); if (!source) { SE_LOG_DEBUG(NULL, NULL, "edsf %s: address book not found", m_uuid.c_str()); @@ -56,23 +58,36 @@ void EDSFView::doStart() } m_store = EdsfPersonaStoreCXX::steal(edsf_persona_store_new_with_source_registry(m_registry, source)); GErrorCXX gerror; - m_ebook = EBookClientCXX::steal( -#ifdef HAVE_E_BOOK_CLIENT_NEW_DIRECT - getenv("SYNCEVOLUTION_NO_PIM_EDS_DIRECT") ? - e_book_client_new(source, gerror) : - e_book_client_new_direct(m_registry, source, gerror) -#elif defined(HAVE_E_BOOK_CLIENT_CONNECT_DIRECT_SYNC) - getenv("SYNCEVOLUTION_NO_PIM_EDS_DIRECT") ? - e_book_client_new(source, gerror) : - E_BOOK_CLIENT(e_book_client_connect_direct_sync(m_registry, source, NULL, gerror)) -#else - e_book_client_new(source, gerror) +#ifdef HAVE_E_BOOK_CLIENT_CONNECT_DIRECT_SYNC + // TODO: use asynchronous version, once there is one in EDS + if (!getenv("SYNCEVOLUTION_NO_PIM_EDS_DIRECT")) { + while (!m_ebook) { + SE_LOG_DEBUG(NULL, NULL, "edsf %s: synchronously connecting direct", m_uuid.c_str()); + m_ebook = EBookClientCXX::steal(E_BOOK_CLIENT(e_book_client_connect_direct_sync(m_registry, source, NULL, gerror))); + if (!m_ebook) { + SE_LOG_DEBUG(NULL, NULL, "edsf %s: no DRA client for address book: %s", m_uuid.c_str(), gerror ? gerror->message : "???"); + if (gerror && g_error_matches(gerror, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) { + SE_LOG_DEBUG(NULL, NULL, "edsf %s: try again", m_uuid.c_str()); + gerror.clear(); + } else { + return; + } + } + } + // Already opened by call above, proceed immediately. + opened(true, NULL); + return; + } #endif - ); + + SE_LOG_DEBUG(NULL, NULL, "edsf %s: new client", m_uuid.c_str()); + m_ebook = EBookClientCXX::steal(e_book_client_new(source, gerror)); if (!m_ebook) { - SE_LOG_DEBUG(NULL, NULL, "edfs %s: no client for address book: %s", m_uuid.c_str(), gerror->message); + SE_LOG_DEBUG(NULL, NULL, "edsf %s: no normal client for address book: %s", m_uuid.c_str(), gerror ? gerror->message : "???"); return; } + + SE_LOG_DEBUG(NULL, NULL, "edsf %s: asynchronous open", m_uuid.c_str()); SYNCEVO_GLIB_CALL_ASYNC(e_client_open, boost::bind(&EDSFView::opened, m_self, @@ -87,9 +102,14 @@ void EDSFView::opened(gboolean success, const GError *gerror) throw() { try { if (!success) { - SE_LOG_DEBUG(NULL, NULL, "edfs %s: opening failed: %s", m_uuid.c_str(), gerror->message); - return; + SE_LOG_DEBUG(NULL, NULL, "edsf %s: opening failed: %s", m_uuid.c_str(), gerror ? gerror->message : "???"); + if (gerror && g_error_matches(gerror, E_CLIENT_ERROR, E_CLIENT_ERROR_BUSY)) { + SE_LOG_DEBUG(NULL, NULL, "edsf %s: try again", m_uuid.c_str()); + doStart(); + return; + } } + SE_LOG_DEBUG(NULL, NULL, "edsf %s: opened successfully, reading contacts asynchronously: %s", m_uuid.c_str(), m_query.c_str()); SYNCEVO_GLIB_CALL_ASYNC(e_book_client_get_contacts, boost::bind(&EDSFView::read, m_self, @@ -107,9 +127,14 @@ void EDSFView::opened(gboolean success, const GError *gerror) throw() void EDSFView::read(gboolean success, GSList *contactslist, const GError *gerror) throw() { try { + SE_LOG_DEBUG(NULL, NULL, "edsf %s: reading contacts completed: %s", + m_uuid.c_str(), + success ? "success" : + gerror ? gerror->message : + "failed without error"); GListCXX<EContact, GSList, GObjectDestructor> contacts(contactslist); if (!success) { - SE_LOG_DEBUG(NULL, NULL, "edfs %s: reading failed: %s", m_uuid.c_str(), gerror->message); + SE_LOG_DEBUG(NULL, NULL, "edsf %s: reading failed: %s", m_uuid.c_str(), gerror->message); return; } |