| | |
| | | |
| | | if (isOperational.getAndSet(false)) { |
| | | // Transition from online to offline. |
| | | if (DEBUG_LOG.isLoggable(Level.WARNING)) { |
| | | DEBUG_LOG.warning(String.format( |
| | | "Connection factory '%s' is no longer operational: %s", factory, error |
| | | .getMessage())); |
| | | synchronized (listenerLock) { |
| | | try { |
| | | listener.handleConnectionFactoryOffline(factory, error); |
| | | } catch (Throwable t) { |
| | | handleListenerException(t); |
| | | } |
| | | } |
| | | |
| | | synchronized (stateLock) { |
| | |
| | | private void notifyOnline() { |
| | | if (!isOperational.getAndSet(true)) { |
| | | // Transition from offline to online. |
| | | if (DEBUG_LOG.isLoggable(Level.INFO)) { |
| | | DEBUG_LOG.info(String.format("Connection factory'%s' is now operational", |
| | | factory)); |
| | | synchronized (listenerLock) { |
| | | try { |
| | | listener.handleConnectionFactoryOnline(factory); |
| | | } catch (Throwable t) { |
| | | handleListenerException(t); |
| | | } |
| | | } |
| | | |
| | | synchronized (stateLock) { |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | private void handleListenerException(Throwable t) { |
| | | if (DEBUG_LOG.isLoggable(Level.SEVERE)) { |
| | | DEBUG_LOG.log(Level.SEVERE, |
| | | "A run-time error occurred while processing a load-balancer event", t); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private final class MonitorRunnable implements Runnable { |
| | |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * A default event listener which just logs the event. |
| | | */ |
| | | private static final LoadBalancerEventListener DEFAULT_LISTENER = |
| | | new LoadBalancerEventListener() { |
| | | |
| | | @Override |
| | | public void handleConnectionFactoryOnline(ConnectionFactory factory) { |
| | | // Transition from offline to online. |
| | | if (DEBUG_LOG.isLoggable(Level.INFO)) { |
| | | DEBUG_LOG.info(String.format("Connection factory'%s' is now operational", |
| | | factory)); |
| | | } |
| | | } |
| | | |
| | | @Override |
| | | public void handleConnectionFactoryOffline(ConnectionFactory factory, |
| | | ErrorResultException error) { |
| | | if (DEBUG_LOG.isLoggable(Level.WARNING)) { |
| | | DEBUG_LOG.warning(String.format( |
| | | "Connection factory '%s' is no longer operational: %s", factory, |
| | | error.getMessage())); |
| | | } |
| | | } |
| | | }; |
| | | |
| | | private final List<MonitoredConnectionFactory> monitoredFactories; |
| | | private final ReferenceCountedObject<ScheduledExecutorService>.Reference scheduler; |
| | | private final Object stateLock = new Object(); |
| | |
| | | private volatile ErrorResultException lastFailure = null; |
| | | |
| | | /** |
| | | * The event listener which should be notified when connection factories go |
| | | * on or off-line. |
| | | */ |
| | | private final LoadBalancerEventListener listener; |
| | | |
| | | /** |
| | | * Ensures that events are notified one at a time. |
| | | */ |
| | | private final Object listenerLock = new Object(); |
| | | |
| | | /** |
| | | * Guarded by stateLock. |
| | | */ |
| | | private int offlineFactoriesCount = 0; |
| | |
| | | this.scheduler = DEFAULT_SCHEDULER.acquireIfNull(scheduler); |
| | | this.monitoringInterval = interval; |
| | | this.monitoringIntervalTimeUnit = unit; |
| | | this.listener = DEFAULT_LISTENER; |
| | | } |
| | | |
| | | @Override |