/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2014 Red Hat, Inc., and individual contributors
 * as indicated by the @author tags.
 *
 * 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 io.undertow.server.handlers.proxy;

The connection pool error handler is intended to be used per node and will therefore be shared across I/O threads.
Author:Emanuel Muckenhuber
/** * The connection pool error handler is intended to be used per node and will therefore be shared across I/O threads. * * @author Emanuel Muckenhuber */
public interface ConnectionPoolErrorHandler {
Check whether pool is available
Returns:whether the pool is available
/** * Check whether pool is available * * @return whether the pool is available */
boolean isAvailable();
Handle a connection error.
Returns:true if the pool is still available, false otherwise
/** * Handle a connection error. * * @return {@code true} if the pool is still available, {@code false} otherwise */
boolean handleError();
Clear the connection errors.
Returns:true if the pool is available again, false otherwise
/** * Clear the connection errors. * * @return {@code true} if the pool is available again, {@code false} otherwise */
boolean clearError(); class SimpleConnectionPoolErrorHandler implements ConnectionPoolErrorHandler { private volatile boolean problem; @Override public boolean isAvailable() { return !problem; } @Override public boolean handleError() { problem = true; return false; } @Override public boolean clearError() { problem = false; return true; } }
Counting error handler, this only propagates the state to the delegate handler after reaching a given limit.
/** * Counting error handler, this only propagates the state to the delegate handler after reaching a given limit. */
class CountingErrorHandler implements ConnectionPoolErrorHandler { private int count; private long timeout; private final long interval; private final int errorCount; private final int successCount; private final ConnectionPoolErrorHandler delegate; public CountingErrorHandler(int errorCount, int successCount, long interval) { this(errorCount, successCount, interval, new SimpleConnectionPoolErrorHandler()); } public CountingErrorHandler(int errorCount, int successCount, long interval, ConnectionPoolErrorHandler delegate) { this.errorCount = Math.max(errorCount, 1); this.successCount = Math.max(successCount, 1); this.interval = Math.max(interval, 0); this.delegate = delegate; } @Override public boolean isAvailable() { return delegate.isAvailable(); } @Override public synchronized boolean handleError() { if (delegate.isAvailable()) { final long time = System.currentTimeMillis(); // If the timeout is reached reset the error count if (time >= timeout) { count = 1; timeout = time + interval; } else { if (count++ == 1) { timeout = time + interval; } } if (count >= errorCount) { return delegate.handleError(); } return true; } else { count = 0; // if in error reset the successful count return false; } } @Override public synchronized boolean clearError() { if (delegate.isAvailable()) { count = 0; // Just reset the error count return true; } else { // Count the successful attempts if (count++ == successCount) { return delegate.clearError(); } return false; } } } }