/*
* Copyright 2017 Couchbase, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.couchbase.mock.memcached.client;
import org.couchbase.mock.memcached.errormap.RetrySpec;
import java.io.IOException;
/**
* Created by mnunberg on 4/20/17.
*/
public class Retryer {
final MemcachedClient client;
final RetrySpec spec;
final byte[] cmd;
public Retryer(MemcachedClient client, RetrySpec spec, byte[] cmd) {
this.client = client;
this.spec = spec;
this.cmd = cmd;
}
private static void accuSleep(long sleepTime) throws InterruptedException {
long timeAfterSleep = System.currentTimeMillis() + sleepTime;
while (System.currentTimeMillis() < timeAfterSleep) {
Thread.sleep(0, 500000);
}
}
/**
* Runs until the retry duration is reached
*/
public void run() throws Exception {
// Send the initial command:
client.sendRequest(cmd);
long endTime = System.currentTimeMillis() + spec.getMaxDuration() + spec.getAfter();
// Wait until the 'after' time
Thread.sleep(spec.getAfter());
int numAttempts = 0;
long now = System.currentTimeMillis();
while (now < endTime) {
client.sendRequest(cmd);
now = System.currentTimeMillis();
numAttempts ++;
// See how to retry:
long sleepTime = 0;
if (spec.isConstant()) {
sleepTime = spec.getInterval();
} else if (spec.isLinear()) {
sleepTime = spec.getInterval() * numAttempts;
} else if (spec.isExponential()) {
sleepTime = (long) Math.pow(spec.getInterval(), numAttempts);
}
if (spec.getCeil() > 0) {
sleepTime = Math.min(spec.getCeil(), sleepTime);
}
if (now + sleepTime > endTime) {
break;
} else {
accuSleep(sleepTime);
now = System.currentTimeMillis();
}
}
}
public void runError() throws Exception {
for (int i = 0; i < 10; i++) {
client.sendRequest(cmd);
}
}
}