private void doRun() { if (isSuspended()) { LOG.trace("Cannot start to poll: {} as its suspended", this.getEndpoint()); return; } // should we backoff if its enabled, and either the idle or error counter is > the threshold if (backoffMultiplier > 0 // either idle or error threshold could be not in use, so check for that and use // MAX_VALUE if not in use && (idleCounter >= (backoffIdleThreshold > 0 ? backoffIdleThreshold : Integer.MAX_VALUE)) || errorCounter >= (backoffErrorThreshold > 0 ? backoffErrorThreshold : Integer.MAX_VALUE)) { if (backoffCounter++ < backoffMultiplier) { // yes we should backoff if (idleCounter > 0) { LOG.debug( "doRun() backoff due subsequent {} idles (backoff at {}/{})", new Object[] {idleCounter, backoffCounter, backoffMultiplier}); } else { LOG.debug( "doRun() backoff due subsequent {} errors (backoff at {}/{})", new Object[] {errorCounter, backoffCounter, backoffMultiplier}); } return; } else { // we are finished with backoff so reset counters idleCounter = 0; errorCounter = 0; backoffCounter = 0; LOG.trace("doRun() backoff finished, resetting counters."); } } int retryCounter = -1; boolean done = false; Throwable cause = null; int polledMessages = 0; while (!done) { try { cause = null; // eager assume we are done done = true; if (isPollAllowed()) { if (retryCounter == -1) { LOG.trace("Starting to poll: {}", this.getEndpoint()); } else { LOG.debug("Retrying attempt {} to poll: {}", retryCounter, this.getEndpoint()); } // mark we are polling which should also include the begin/poll/commit polling = true; try { boolean begin = pollStrategy.begin(this, getEndpoint()); if (begin) { retryCounter++; polledMessages = poll(); LOG.trace("Polled {} messages", polledMessages); if (polledMessages == 0 && isSendEmptyMessageWhenIdle()) { // send an "empty" exchange processEmptyMessage(); } pollStrategy.commit(this, getEndpoint(), polledMessages); if (polledMessages > 0 && isGreedy()) { done = false; retryCounter = -1; LOG.trace("Greedy polling after processing {} messages", polledMessages); } } else { LOG.debug("Cannot begin polling as pollStrategy returned false: {}", pollStrategy); } } finally { polling = false; } } LOG.trace("Finished polling: {}", this.getEndpoint()); } catch (Exception e) { try { boolean retry = pollStrategy.rollback(this, getEndpoint(), retryCounter, e); if (retry) { // do not set cause as we retry done = false; } else { cause = e; done = true; } } catch (Throwable t) { cause = t; done = true; } } catch (Throwable t) { cause = t; done = true; } if (cause != null && isRunAllowed()) { // let exception handler deal with the caused exception // but suppress this during shutdown as the logs may get flooded with exceptions during // shutdown/forced shutdown try { getExceptionHandler() .handleException( "Consumer " + this + " failed polling endpoint: " + getEndpoint() + ". Will try again at next poll", cause); } catch (Throwable e) { LOG.warn("Error handling exception. This exception will be ignored.", e); } } } if (cause != null) { idleCounter = 0; errorCounter++; } else { idleCounter = polledMessages == 0 ? ++idleCounter : 0; errorCounter = 0; } LOG.trace("doRun() done with idleCounter={}, errorCounter={}", idleCounter, errorCounter); // avoid this thread to throw exceptions because the thread pool wont re-schedule a new thread }