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.exceptions.StorageException; 20 : import com.google.gerrit.index.query.InternalQuery; 21 : import com.google.inject.Provider; 22 : import java.util.function.Consumer; 23 : import java.util.function.Predicate; 24 : 25 : /** 26 : * An action to query an index that is executed with retrying. 27 : * 28 : * <p>Instances of this class are created via {@link RetryHelper#accountIndexQuery(String, 29 : * IndexQueryAction)} and {@link RetryHelper#changeIndexQuery(String, IndexQueryAction)}. 30 : * 31 : * <p>In contrast to normal {@link RetryableAction.Action}s that are called via {@link 32 : * RetryableAction} {@link IndexQueryAction}s get a {@link InternalQuery} provided. 33 : * 34 : * <p>In addition when an index query action is called any exception that is not an unchecked 35 : * exception gets wrapped into an {@link StorageException}. 36 : */ 37 : public class RetryableIndexQueryAction<Q extends InternalQuery<?, Q>, T> 38 : extends RetryableAction<T> { 39 : @FunctionalInterface 40 : public interface IndexQueryAction<T, Q> { 41 : T call(Q internalQuery) throws Exception; 42 : } 43 : 44 : RetryableIndexQueryAction( 45 : RetryHelper retryHelper, 46 : Provider<Q> internalQuery, 47 : String actionName, 48 : IndexQueryAction<T, Q> indexQuery) { 49 61 : super( 50 : retryHelper, 51 : ActionType.INDEX_QUERY, 52 : actionName, 53 61 : () -> indexQuery.call(internalQuery.get())); 54 61 : } 55 : 56 : @Override 57 : public RetryableIndexQueryAction<Q, T> retryOn(Predicate<Throwable> exceptionPredicate) { 58 0 : super.retryOn(exceptionPredicate); 59 0 : return this; 60 : } 61 : 62 : @Override 63 : public RetryableIndexQueryAction<Q, T> retryWithTrace(Predicate<Throwable> exceptionPredicate) { 64 0 : super.retryWithTrace(exceptionPredicate); 65 0 : return this; 66 : } 67 : 68 : @Override 69 : public RetryableIndexQueryAction<Q, T> onAutoTrace(Consumer<String> traceIdConsumer) { 70 0 : super.onAutoTrace(traceIdConsumer); 71 0 : return this; 72 : } 73 : 74 : @Override 75 : public RetryableIndexQueryAction<Q, T> listener(RetryListener retryListener) { 76 0 : super.listener(retryListener); 77 0 : return this; 78 : } 79 : 80 : @Override 81 : public RetryableIndexQueryAction<Q, T> defaultTimeoutMultiplier(int multiplier) { 82 0 : super.defaultTimeoutMultiplier(multiplier); 83 0 : return this; 84 : } 85 : 86 : @Override 87 : public T call() { 88 : try { 89 61 : return super.call(); 90 0 : } catch (Exception e) { 91 0 : Throwables.throwIfUnchecked(e); 92 0 : throw new StorageException(e); 93 : } 94 : } 95 : }