Search in sources :

Example 1 with TaskResult

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);
        }
    }
}
Also used : TaskResult(com.wavefront.agent.data.TaskResult)

Example 2 with TaskResult

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);
        }
    }
}
Also used : TaskResult(com.wavefront.agent.data.TaskResult)

Example 3 with TaskResult

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);
    }
}
Also used : SourceTagSubmissionTask(com.wavefront.agent.data.SourceTagSubmissionTask) ArrayList(java.util.ArrayList) SourceTag(com.wavefront.dto.SourceTag) TaskResult(com.wavefront.agent.data.TaskResult)

Aggregations

TaskResult (com.wavefront.agent.data.TaskResult)3 SourceTagSubmissionTask (com.wavefront.agent.data.SourceTagSubmissionTask)1 SourceTag (com.wavefront.dto.SourceTag)1 ArrayList (java.util.ArrayList)1