RetryHelper: Let callers care about exception handling

When retrying actions it is specific to the caller which exceptions
should be rethrown and which exceptions should be wrapped. At the moment
RetryHelper has 2 kinds of execute methods that are suitable for change
updates and account updates. These execute methods do not fit for all
cases, e.g. ReceiveCommits uses RetryHelper to retry change queries, but
the execute method requires handling of ConfigInvalidException which
cannot occur during index queries.

Instead of adding more specific execute methods to RetryHelper, just let
the execute method throw Exception and let the caller take care about
the exception handling. The execute method that is specific for change
updates is kept in RetryHelper because it has many callers. All other
exception handling is currently unique for one caller, hence it's not
needed to keep a specialized execute method for these cases in
RetryHelper. We can add more specifc execute methods to RetryHelper once
the same exception handling is required by multiple callers to share
the exception handling code.

Change-Id: I7cf2b92fb228d2d6dddd89df5c338e53a2f8f526
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin
2018-01-15 12:55:29 +01:00
parent b65e264faa
commit 14e65d16dc
3 changed files with 51 additions and 32 deletions

View File

@@ -41,6 +41,7 @@ import static org.eclipse.jgit.transport.ReceiveCommand.Result.REJECTED_OTHER_RE
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.ImmutableList;
@@ -149,6 +150,7 @@ import com.google.gerrit.server.update.Context;
import com.google.gerrit.server.update.RepoContext;
import com.google.gerrit.server.update.RepoOnlyOp;
import com.google.gerrit.server.update.RetryHelper;
import com.google.gerrit.server.update.RetryHelper.Action;
import com.google.gerrit.server.update.RetryHelper.ActionType;
import com.google.gerrit.server.update.UpdateException;
import com.google.gerrit.server.util.LabelVote;
@@ -2891,10 +2893,7 @@ class ReceiveCommits {
for (Ref ref : byCommit.get(c.copy())) {
PatchSet.Id psId = PatchSet.Id.fromRef(ref.getName());
Optional<ChangeData> cd =
retryHelper.execute(
ActionType.CHANGE_QUERY,
() -> byLegacyId(psId.getParentKey()),
t -> t instanceof OrmException);
executeIndexQuery(() -> byLegacyId(psId.getParentKey()));
if (cd.isPresent() && cd.get().change().getDest().equals(branch)) {
existingPatchSets++;
bu.addOp(
@@ -2906,11 +2905,7 @@ class ReceiveCommits {
for (String changeId : c.getFooterLines(CHANGE_ID)) {
if (byKey == null) {
byKey =
retryHelper.execute(
ActionType.CHANGE_QUERY,
() -> openChangesByKeyByBranch(branch),
t -> t instanceof OrmException);
byKey = executeIndexQuery(() -> openChangesByKeyByBranch(branch));
}
ChangeNotes onto = byKey.get(new Change.Key(changeId.trim()));
@@ -2967,6 +2962,16 @@ class ReceiveCommits {
}
}
private <T> T executeIndexQuery(Action<T> action) throws OrmException {
try {
return retryHelper.execute(ActionType.INDEX_QUERY, action, OrmException.class::isInstance);
} catch (Exception e) {
Throwables.throwIfUnchecked(e);
Throwables.throwIfInstanceOf(e, OrmException.class);
throw new OrmException(e);
}
}
private void updateAccountInfo() {
if (setFullNameTo == null) {
return;