Finish indexing before sending email

Project watches need to see the most up-to-date information about a
change when evaluating their watch predicates. The match()
implementation for predicates over full-text fields is to search the
secondary index for "id:X field:{text}", which means the secondary
index update needs to be completed before even beginning to send the
email.

For example, if there is a watch for "message:foo", the user wants to
be notified on a new patch set only if the new commit message contains
"foo". Since the predicate "new commit message contains 'foo'" is
evaluated by executing a full-text search on the secondary index, we
need to ensure the secondary index is up to date. Prior to this
change, if the user pushed a new patch set _not_ containing "foo", the
watch evaluation would be racing with the index update, resulting in
the project watch possibly matching against an old version of the
commit message.

To ensure this in all cases, we have to do a lot more synchronous
indexing steps. Very few index operations can now be async, but that's
fine.

(In theory we could split up the email interface to collect recipient
information synchronously but still do the actual sending
asynchronously, but that's considerably more work, and will probably
wait until a hypothetical future when we rewrite the email processing
entirely.)

Checked all callers of indexAsync to find all instances of this bug.

Change-Id: I7f6d6e42fe45c64749205cdbc1a0105a39e90fbe
This commit is contained in:
Dave Borowitz
2015-04-16 15:58:23 -07:00
parent b8a120b338
commit 87295b6fbb
8 changed files with 8 additions and 38 deletions

View File

@@ -255,8 +255,8 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
ImmutableList.of(psa)));
}
accountLoaderFactory.create(true).fill(result.reviewers);
emailReviewers(rsrc.getChange(), added);
indexFuture.checkedGet();
emailReviewers(rsrc.getChange(), added);
if (!added.isEmpty()) {
PatchSet patchSet = dbProvider.get().patchSets().get(rsrc.getChange().currentPatchSetId());
for (PatchSetApproval psa : added) {