Hi, I've been working on an application that keeps a read-only handle on the notmuch database open for a long time. In some cases when a new message is added along with some renames of other messages using 'notmuch new' while the application is running I get an Xapian exception: DatabaseModifiedError:
A Xapian exception occurred performing query: The revision being read has been discarded - you should call Xapian::Database::reopen() and retry the operation. Which seems to be printed from: notmuch_query_search_threads -> notmuch_query_search_messages:294. I have not been able to make a smaller test case at the moment (this happens with offlineimap updating an maildir and notmuch new run afterwards + some tagging). I can work around this by checking for a NULL pointer returned from notmuch_query_search_threads () and re-open the database (notmuch_database_close () -> notmuch_database_open ()). But I have no way of knowing programatically if this really is the error that has happened. There should be some way of propagating the error information or (even better for my case; for notmuch to reopen the database), one option is the Gmime way of passing an pointer to an error structure that is filled up by the notmuch interface function. I made some attempts at exposing the ::reopen() function as suggested by Xapian (http://xapian.org/docs/apidoc/html/classXapian_1_1Database.html#af140b1f8d948d13cf7be4a11a7c699a4), but I end up with other errors afterwards. Possibly from leftover structures created with the original database handle: after notmuch_database_reopen (see attached patch for your reference): A Xapian exception occurred when reading header: Expected block 24615 to be level 1, not 0 A Xapian exception occurred when reading header: Error reading block 419480589: got end of file A Xapian exception occurred when reading date: Error reading block 419480589: got end of file A Xapian exception occurred when reading header: Error reading block 419480589: got end of file as mentioned, doing a manual _close and _open works. Again, the best would be a consistent way to really know that this (or something else) is the error that really happened. Cheers, Gaute
From 90340fe59d677c989352f08e82f908016c25fafa Mon Sep 17 00:00:00 2001 From: Gaute Hope <[email protected]> Date: Mon, 11 Aug 2014 14:16:12 +0200 Subject: [PATCH] lib: expose XapianDatabae::reopen() through notmuch_database_reopen() --- lib/database.cc | 18 ++++++++++++++++++ lib/notmuch.h | 22 ++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/lib/database.cc b/lib/database.cc index c760290..80af410 100644 --- a/lib/database.cc +++ b/lib/database.cc @@ -778,6 +778,24 @@ notmuch_database_open (const char *path, } notmuch_status_t +notmuch_database_reopen (notmuch_database_t *notmuch) +{ + try { + notmuch->xapian_db->reopen (); + + return NOTMUCH_STATUS_SUCCESS; + + } catch (const Xapian::Error &error) { + if (! notmuch->exception_reported) { + fprintf (stderr, "Error: A Xapian exception occurred while reopening database: %s\n", + error.get_msg().c_str()); + } + + return NOTMUCH_STATUS_XAPIAN_EXCEPTION; + } +} + +notmuch_status_t notmuch_database_close (notmuch_database_t *notmuch) { notmuch_status_t status = NOTMUCH_STATUS_SUCCESS; diff --git a/lib/notmuch.h b/lib/notmuch.h index 3c5ec98..00950af 100644 --- a/lib/notmuch.h +++ b/lib/notmuch.h @@ -277,6 +277,28 @@ notmuch_database_open (const char *path, notmuch_database_t **database); /** + * Reopen the given notmuch database. + * + * The underlying Xapian database will be re-opened to the latest + * available version. It can be used to make sure the latest results + * are returned or to recover from an Xapaian::DatabaseModifiedError + * which can occur after external database modification. + * + * Calling notmuch_database_reopen on a database that has been closed + * will result in a NOTMUCH_STATUS_XAPAIAN_EXCEPTION. + * + * Return value: + * + * NOTMUCH_STATUS_SUCCESS: Successfully reopened database. + * + * NOTMUCH_STATUS_XAPIAN_EXCEPTION: A Xapian exception occurred. + * + */ +notmuch_status_t +notmuch_database_reopen (notmuch_database_t *database); + + +/** * Close the given notmuch database. * * After notmuch_database_close has been called, calls to other -- 2.0.3
_______________________________________________ notmuch mailing list [email protected] http://notmuchmail.org/mailman/listinfo/notmuch
