mirror of
https://git.notmuchmail.org/git/notmuch
synced 2024-11-22 10:58:10 +01:00
lib: handle DatabaseModifiedError in _n_message_ensure_metadata
The retries are hardcoded to a small number, and error handling aborts than propagating errors from notmuch_database_reopen. These are both somewhat justified by the assumption that most things that can go wrong in Xapian::Database::reopen are rare and fatal. Here's the brief discussion with Xapian upstream: 24-02-2017 08:12:57 < bremner> any intuition about how likely Xapian::Database::reopen is to fail? I'm catching a DatabaseModifiedError somewhere where handling any further errors is tricky, and wondering about treating a failed reopen as as "the impossible happened, stopping" 24-02-2017 16:22:34 < olly> bremner: there should not be much scope for failure - stuff like out of memory or disk errors, which are probably a good enough excuse to stop
This commit is contained in:
parent
e17a914b77
commit
e0b22c139c
2 changed files with 85 additions and 64 deletions
|
@ -49,6 +49,9 @@ struct visible _notmuch_message {
|
||||||
/* Message document modified since last sync */
|
/* Message document modified since last sync */
|
||||||
notmuch_bool_t modified;
|
notmuch_bool_t modified;
|
||||||
|
|
||||||
|
/* last view of database the struct is synced with */
|
||||||
|
unsigned long last_view;
|
||||||
|
|
||||||
Xapian::Document doc;
|
Xapian::Document doc;
|
||||||
Xapian::termcount termpos;
|
Xapian::termcount termpos;
|
||||||
};
|
};
|
||||||
|
@ -110,6 +113,9 @@ _notmuch_message_create_for_document (const void *talloc_owner,
|
||||||
message->flags = 0;
|
message->flags = 0;
|
||||||
message->lazy_flags = 0;
|
message->lazy_flags = 0;
|
||||||
|
|
||||||
|
/* the message is initially not synchronized with Xapian */
|
||||||
|
message->last_view = 0;
|
||||||
|
|
||||||
/* Each of these will be lazily created as needed. */
|
/* Each of these will be lazily created as needed. */
|
||||||
message->message_id = NULL;
|
message->message_id = NULL;
|
||||||
message->thread_id = NULL;
|
message->thread_id = NULL;
|
||||||
|
@ -314,6 +320,7 @@ static void
|
||||||
_notmuch_message_ensure_metadata (notmuch_message_t *message)
|
_notmuch_message_ensure_metadata (notmuch_message_t *message)
|
||||||
{
|
{
|
||||||
Xapian::TermIterator i, end;
|
Xapian::TermIterator i, end;
|
||||||
|
|
||||||
const char *thread_prefix = _find_prefix ("thread"),
|
const char *thread_prefix = _find_prefix ("thread"),
|
||||||
*tag_prefix = _find_prefix ("tag"),
|
*tag_prefix = _find_prefix ("tag"),
|
||||||
*id_prefix = _find_prefix ("id"),
|
*id_prefix = _find_prefix ("id"),
|
||||||
|
@ -327,7 +334,8 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message)
|
||||||
* slightly more costly than looking up individual fields if only
|
* slightly more costly than looking up individual fields if only
|
||||||
* one field of the message object is actually used, it's a huge
|
* one field of the message object is actually used, it's a huge
|
||||||
* win as more fields are used. */
|
* win as more fields are used. */
|
||||||
|
for (int count=0; count < 3; count++) {
|
||||||
|
try {
|
||||||
i = message->doc.termlist_begin ();
|
i = message->doc.termlist_begin ();
|
||||||
end = message->doc.termlist_end ();
|
end = message->doc.termlist_end ();
|
||||||
|
|
||||||
|
@ -394,6 +402,20 @@ _notmuch_message_ensure_metadata (notmuch_message_t *message)
|
||||||
* header. For these cases, we return an empty string. */
|
* header. For these cases, we return an empty string. */
|
||||||
if (!message->in_reply_to)
|
if (!message->in_reply_to)
|
||||||
message->in_reply_to = talloc_strdup (message, "");
|
message->in_reply_to = talloc_strdup (message, "");
|
||||||
|
|
||||||
|
/* all the way without an exception */
|
||||||
|
break;
|
||||||
|
} catch (const Xapian::DatabaseModifiedError &error) {
|
||||||
|
notmuch_status_t status = _notmuch_database_reopen (message->notmuch);
|
||||||
|
if (status != NOTMUCH_STATUS_SUCCESS)
|
||||||
|
INTERNAL_ERROR ("unhandled error from notmuch_database_reopen: %s\n",
|
||||||
|
notmuch_status_to_string (status));
|
||||||
|
} catch (const Xapian::Error &error) {
|
||||||
|
INTERNAL_ERROR ("A Xapian exception occurred fetching message metadata: %s\n",
|
||||||
|
error.get_msg().c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
message->last_view = message->notmuch->view;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -6,7 +6,6 @@ test_description="DatabaseModifiedError handling"
|
||||||
add_email_corpus
|
add_email_corpus
|
||||||
|
|
||||||
test_begin_subtest "catching DatabaseModifiedError in _notmuch_message_ensure_metadata"
|
test_begin_subtest "catching DatabaseModifiedError in _notmuch_message_ensure_metadata"
|
||||||
test_subtest_known_broken
|
|
||||||
# it seems to need to be an early document to trigger the exception
|
# it seems to need to be an early document to trigger the exception
|
||||||
first_id=$(notmuch search --output=messages '*'| head -1 | sed s/^id://)
|
first_id=$(notmuch search --output=messages '*'| head -1 | sed s/^id://)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue