use of com.wavefront.agent.data.TaskResult in project java by wavefrontHQ.
the class QueueProcessor method run.
@Override
public void run() {
if (!isRunning.get())
return;
int successes = 0;
int failures = 0;
boolean rateLimiting = false;
try {
while (taskQueue.size() > 0 && taskQueue.size() > failures) {
if (!isRunning.get() || Thread.currentThread().isInterrupted())
return;
if (storedTask == null) {
storedTask = Suppliers.memoizeWithExpiration(taskQueue::peek, 500, TimeUnit.MILLISECONDS);
}
T task = storedTask.get();
int taskSize = task == null ? 0 : task.weight();
this.headTaskTimestamp = task == null ? Long.MAX_VALUE : task.getEnqueuedMillis();
int permitsNeeded = Math.min((int) rateLimiter.getRate(), taskSize);
if (!rateLimiter.immediatelyAvailable(permitsNeeded)) {
// if there's less than 1 second worth of accumulated credits,
// don't process the backlog queue
rateLimiting = true;
break;
}
if (taskSize > 0) {
rateLimiter.acquire(taskSize);
}
boolean removeTask = true;
try {
if (task != null) {
taskInjector.inject(task);
TaskResult result = task.execute();
switch(result) {
case DELIVERED:
successes++;
break;
case PERSISTED:
rateLimiter.recyclePermits(taskSize);
failures++;
return;
case PERSISTED_RETRY:
rateLimiter.recyclePermits(taskSize);
failures++;
break;
case RETRY_LATER:
removeTask = false;
rateLimiter.recyclePermits(taskSize);
failures++;
}
}
if (failures >= 10) {
break;
}
} finally {
if (removeTask) {
taskQueue.remove();
if (taskQueue.size() == 0)
schedulerTimingFactor = 1.0d;
storedTask = null;
}
}
}
if (taskQueue.size() == 0)
headTaskTimestamp = Long.MAX_VALUE;
} catch (Throwable ex) {
logger.log(Level.WARNING, "Unexpected exception", ex);
} finally {
long nextFlush;
if (rateLimiting) {
logger.fine("[" + handlerKey.getHandle() + "] Rate limiter active, will re-attempt later " + "to prioritize eal-time traffic.");
// if proxy rate limit exceeded, try again in 1/4 to 1/2 flush interval
// (to introduce some degree of fairness)
nextFlush = (int) ((1 + Math.random()) * runtimeProperties.getPushFlushInterval() / 4 * schedulerTimingFactor);
} else {
if (successes == 0 && failures > 0) {
// caps at 2*base^4
backoffExponent = Math.min(4, backoffExponent + 1);
} else {
backoffExponent = 1;
}
nextFlush = (long) ((Math.random() + 1.0) * runtimeProperties.getPushFlushInterval() * Math.pow(globalProps.getRetryBackoffBaseSeconds(), backoffExponent) * schedulerTimingFactor);
logger.fine("[" + handlerKey.getHandle() + "] Next run scheduled in " + nextFlush + "ms");
}
if (isRunning.get()) {
scheduler.schedule(this, nextFlush, TimeUnit.MILLISECONDS);
}
}
}
use of com.wavefront.agent.data.TaskResult in project java by wavefrontHQ.
the class AbstractSenderTask method run.
@Override
public void run() {
if (!isRunning.get())
return;
long nextRunMillis = properties.getPushFlushInterval();
isSending = true;
try {
List<T> current = createBatch();
int currentBatchSize = current.size();
if (currentBatchSize == 0)
return;
if (rateLimiter == null || rateLimiter.tryAcquire(currentBatchSize)) {
TaskResult result = processSingleBatch(current);
this.attemptedCounter.inc(currentBatchSize);
switch(result) {
case DELIVERED:
break;
case PERSISTED:
case PERSISTED_RETRY:
if (rateLimiter != null)
rateLimiter.recyclePermits(currentBatchSize);
break;
case RETRY_LATER:
undoBatch(current);
if (rateLimiter != null)
rateLimiter.recyclePermits(currentBatchSize);
default:
}
} else {
// if proxy rate limit exceeded, try again in 1/4..1/2 of flush interval
// to introduce some degree of fairness.
nextRunMillis = nextRunMillis / 4 + (int) (Math.random() * nextRunMillis / 4);
final long willRetryIn = nextRunMillis;
throttledLogger.log(Level.INFO, () -> "[" + handlerKey.getHandle() + " thread " + threadId + "]: WF-4 Proxy rate limiter active (pending " + handlerKey.getEntityType() + ": " + datum.size() + "), will retry in " + willRetryIn + "ms");
undoBatch(current);
}
} catch (Throwable t) {
logger.log(Level.SEVERE, "Unexpected error in flush loop", t);
} finally {
isSending = false;
if (isRunning.get()) {
scheduler.schedule(this, nextRunMillis, TimeUnit.MILLISECONDS);
}
}
}
use of com.wavefront.agent.data.TaskResult in project java by wavefrontHQ.
the class SourceTagSenderTask method run.
@Override
public void run() {
long nextRunMillis = properties.getPushFlushInterval();
isSending = true;
try {
List<SourceTag> current = createBatch();
if (current.size() == 0)
return;
Iterator<SourceTag> iterator = current.iterator();
while (iterator.hasNext()) {
if (rateLimiter == null || rateLimiter.tryAcquire()) {
SourceTag tag = iterator.next();
SourceTagSubmissionTask task = new SourceTagSubmissionTask(proxyAPI, properties, backlog, handlerKey.getHandle(), tag, null);
TaskResult result = task.execute();
this.attemptedCounter.inc();
switch(result) {
case DELIVERED:
continue;
case PERSISTED:
case PERSISTED_RETRY:
if (rateLimiter != null)
rateLimiter.recyclePermits(1);
continue;
case RETRY_LATER:
final List<SourceTag> remainingItems = new ArrayList<>();
remainingItems.add(tag);
iterator.forEachRemaining(remainingItems::add);
undoBatch(remainingItems);
if (rateLimiter != null)
rateLimiter.recyclePermits(1);
return;
default:
}
} else {
final List<SourceTag> remainingItems = new ArrayList<>();
iterator.forEachRemaining(remainingItems::add);
undoBatch(remainingItems);
// if proxy rate limit exceeded, try again in 1/4..1/2 of flush interval
// to introduce some degree of fairness.
nextRunMillis = (int) (1 + Math.random()) * nextRunMillis / 4;
final long willRetryIn = nextRunMillis;
throttledLogger.log(Level.INFO, () -> "[" + handlerKey.getHandle() + " thread " + threadId + "]: WF-4 Proxy rate limiter " + "active (pending " + handlerKey.getEntityType() + ": " + datum.size() + "), will retry in " + willRetryIn + "ms");
return;
}
}
} catch (Throwable t) {
logger.log(Level.SEVERE, "Unexpected error in flush loop", t);
} finally {
isSending = false;
scheduler.schedule(this, nextRunMillis, TimeUnit.MILLISECONDS);
}
}
Aggregations