Extract detection of LOCK_FAILURE errors into an ExceptionHook

ExceptionHook allows implementors to detect and handle exceptions that
are caused by temporary errors, and hence should cause a retry of the
failed operation. We should make use of it to detect and handle
LOCK_FAILURE errors. This way the code to detect LOCK_FAILURE is in a
single place instead of in RetryHelper for change actions and in
RestApiServlet for REST requests. As it turns out the detection of
LOCK_FAILURE errors in these places was inconsistent, RetryHelper did
unwrapping for UpdateException and StorageException, while
RestApiServlet did unwrapping only for UpdateException. Due to this some
LOCK_FAILURE errors such as [1] didn't trigger request retries.

[1]
com.google.gerrit.exceptions.StorageException: Star change 133855 for account 6003 failed
        at com.google.gerrit.server.StarredChangesUtil.star(StarredChangesUtil.java:234)
        at com.google.gerrit.server.restapi.account.StarredChanges$Create.apply(StarredChanges.java:133)
        at com.google.gerrit.server.restapi.account.StarredChanges$Create.apply(StarredChanges.java:97)
        at com.google.gerrit.httpd.restapi.RestApiServlet.lambda$invokeRestCollectionCreateViewWithRetry$5(RestApiServlet.java:758)
        at com.github.rholder.retry.AttemptTimeLimiters$NoAttemptTimeLimit.call(AttemptTimeLimiters.java:78)
        at com.github.rholder.retry.Retryer.call(Retryer.java:160)
        at com.google.gerrit.server.update.RetryHelper.executeWithTimeoutCount(RetryHelper.java:417)
        at com.google.gerrit.server.update.RetryHelper.executeWithAttemptAndTimeoutCount(RetryHelper.java:368)
        at com.google.gerrit.server.update.RetryHelper.execute(RetryHelper.java:271)
        at com.google.gerrit.httpd.restapi.RestApiServlet.invokeRestEndpointWithRetry(RestApiServlet.java:820)
        at com.google.gerrit.httpd.restapi.RestApiServlet.invokeRestCollectionCreateViewWithRetry(RestApiServlet.java:753)
        at com.google.gerrit.httpd.restapi.RestApiServlet.service(RestApiServlet.java:527)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        ...
Caused by: com.google.gerrit.git.LockFailureException: Update star labels on ref refs/starred-changes/55/133855/6003 failed
        at com.google.gerrit.server.StarredChangesUtil.updateLabels(StarredChangesUtil.java:484)
        at com.google.gerrit.server.StarredChangesUtil.star(StarredChangesUtil.java:227)
        ... 208 more

Signed-off-by: Edwin Kempin <ekempin@google.com>
Change-Id: Ia7162ee5441d72b9ed32ff5b145b93d8626713c6
This commit is contained in:
Edwin Kempin
2019-11-20 15:13:26 +01:00
parent 8a524021c9
commit fc417a149b
4 changed files with 61 additions and 43 deletions

View File

@@ -79,6 +79,7 @@ import com.google.gerrit.server.CmdLineParserModule;
import com.google.gerrit.server.CreateGroupPermissionSyncer;
import com.google.gerrit.server.DynamicOptions;
import com.google.gerrit.server.ExceptionHook;
import com.google.gerrit.server.ExceptionHookImpl;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.RequestListener;
import com.google.gerrit.server.TraceRequestListener;
@@ -393,6 +394,7 @@ public class GerritGlobalModule extends FactoryModule {
DynamicSet.bind(binder(), RequestListener.class).to(TraceRequestListener.class);
DynamicSet.setOf(binder(), ChangeETagComputation.class);
DynamicSet.setOf(binder(), ExceptionHook.class);
DynamicSet.bind(binder(), ExceptionHook.class).to(ExceptionHookImpl.class);
DynamicSet.setOf(binder(), MailSoyTemplateProvider.class);
DynamicMap.mapOf(binder(), MailFilter.class);