001/*******************************************************************************
002 * Copyright (c) 2006-2014 Nuxeo SA (http://nuxeo.com/) and others.
003 * 
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 ******************************************************************************/
009package org.nuxeo.ecm.core.redis.retry;
010
011import org.apache.commons.logging.LogFactory;
012
013public class Retry {
014
015    public interface Block<T> {
016        T retry() throws FailException, ContinueException;
017    }
018
019    public interface Policy {
020        boolean allow();
021
022        void pause();
023    }
024
025    public static class ContinueException extends Exception {
026
027        private static final long serialVersionUID = 1L;
028
029        public ContinueException(Throwable cause) {
030            super(cause);
031        }
032
033    }
034
035    public static class FailException extends Exception {
036
037        public FailException(String message) {
038            super(message);
039        }
040
041        public FailException(Throwable cause) {
042            super(cause);
043        }
044
045        private static final long serialVersionUID = 1L;
046
047    }
048
049    public <T> T retry(Block<T> block, Policy policy) throws FailException {
050        FailException causes = new FailException(
051                "Cannot execute block, retry policy failed, check supressed exception for more infos");
052        while (policy.allow()) {
053            try {
054                return block.retry();
055            } catch (ContinueException error) {
056                causes.addSuppressed(error.getCause());
057            } catch (FailException error) {
058                causes.addSuppressed(error.getCause());
059                throw causes;
060            }
061            policy.pause();
062        }
063        throw causes;
064    }
065
066}