Line data Source code
1 : // Copyright (C) 2019 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.update; 16 : 17 : import com.github.rholder.retry.RetryListener; 18 : import com.google.common.base.Throwables; 19 : import com.google.gerrit.extensions.restapi.RestApiException; 20 : import java.util.function.Consumer; 21 : import java.util.function.Predicate; 22 : 23 : /** 24 : * A change action that is executed with retrying. 25 : * 26 : * <p>Instances of this class are created via {@link RetryHelper#changeUpdate(String, 27 : * ChangeAction)}. 28 : * 29 : * <p>In contrast to normal {@link RetryableAction.Action}s that are called via {@link 30 : * RetryableAction} {@link ChangeAction}s get a {@link BatchUpdate.Factory} provided. 31 : * 32 : * <p>In addition when a change action is called any exception that is not an unchecked exception 33 : * and neither {@link UpdateException} nor {@link RestApiException} get wrapped into an {@link 34 : * UpdateException}. 35 : */ 36 : public class RetryableChangeAction<T> extends RetryableAction<T> { 37 : @FunctionalInterface 38 : public interface ChangeAction<T> { 39 : T call(BatchUpdate.Factory batchUpdateFactory) throws Exception; 40 : } 41 : 42 : RetryableChangeAction( 43 : RetryHelper retryHelper, 44 : BatchUpdate.Factory updateFactory, 45 : String actionName, 46 : ChangeAction<T> changeAction) { 47 70 : super( 48 70 : retryHelper, ActionType.CHANGE_UPDATE, actionName, () -> changeAction.call(updateFactory)); 49 70 : } 50 : 51 : @Override 52 : public RetryableChangeAction<T> retryOn(Predicate<Throwable> exceptionPredicate) { 53 53 : super.retryOn(exceptionPredicate); 54 53 : return this; 55 : } 56 : 57 : @Override 58 : public RetryableChangeAction<T> retryWithTrace(Predicate<Throwable> exceptionPredicate) { 59 0 : super.retryWithTrace(exceptionPredicate); 60 0 : return this; 61 : } 62 : 63 : @Override 64 : public RetryableChangeAction<T> onAutoTrace(Consumer<String> traceIdConsumer) { 65 0 : super.onAutoTrace(traceIdConsumer); 66 0 : return this; 67 : } 68 : 69 : @Override 70 : public RetryableChangeAction<T> listener(RetryListener retryListener) { 71 53 : super.listener(retryListener); 72 53 : return this; 73 : } 74 : 75 : @Override 76 : public RetryableChangeAction<T> defaultTimeoutMultiplier(int multiplier) { 77 67 : super.defaultTimeoutMultiplier(multiplier); 78 67 : return this; 79 : } 80 : 81 : @Override 82 : public T call() throws UpdateException, RestApiException { 83 : try { 84 70 : return super.call(); 85 18 : } catch (Exception e) { 86 17 : Throwables.throwIfUnchecked(e); 87 17 : Throwables.throwIfInstanceOf(e, UpdateException.class); 88 0 : Throwables.throwIfInstanceOf(e, RestApiException.class); 89 0 : throw new UpdateException(e); 90 : } 91 : } 92 : }