package org.corfudb.runtime.view.replication; import org.corfudb.protocols.wireprotocol.ILogData; import org.corfudb.runtime.exceptions.HoleFillRequiredException; import javax.annotation.Nonnull; import java.util.function.Function; /** A hole filling policy which reads several times, * waiting a static amount of time in between, before * requiring a hole fill. * * Created by mwei on 4/6/17. */ public class ReadWaitHoleFillPolicy implements IHoleFillPolicy { /** The amount of time to wait between reads, in milliseconds. */ final int waitMs; /** The amount of times to retry before requiring a hole fill. */ final int numRetries; /** Create a ReadWaitHoleFillPolicy with the given wait times * and retries. * @param waitMs The amount of time to wait before retrying. * @param numRetries The number of retries to apply before requiring a * hole fill. */ public ReadWaitHoleFillPolicy(int waitMs, int numRetries) { this.waitMs = waitMs; this.numRetries = numRetries; } /** {@inheritDoc} */ @Nonnull @Override public ILogData peekUntilHoleFillRequired(long address, Function<Long, ILogData> peekFunction) throws HoleFillRequiredException { int tryNum = 0; do { // If this is not the first try, sleep before trying again if (tryNum != 0) { try { Thread.sleep(waitMs); } catch (Exception e) { throw new RuntimeException(e); } } // Try the read ILogData data = peekFunction.apply(address); // If it was not null, we can return it. if (data != null) { return data; } // Otherwise increment the counter and try again. tryNum++; } while (numRetries > tryNum); throw new HoleFillRequiredException("No data after " + tryNum + " retries"); } }