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.
This commit is contained in:
parent
065fdcd343
commit
e3f0a297f7
2 changed files with 59 additions and 28 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
#endif
|
||||
);
|
||||
if (!m_ebook) {
|
||||
SE_LOG_DEBUG(NULL, NULL, "edfs %s: no client for address book: %s", m_uuid.c_str(), gerror->message);
|
||||
#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, "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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue