mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

boli
22.55.2009 1fbc9df5d0c44ae72c76dacc3c945d4f0d641ee6
sdk/src/org/opends/sdk/HeartBeatConnectionFactory.java
@@ -32,13 +32,13 @@
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import org.opends.sdk.requests.*;
import org.opends.sdk.responses.*;
import org.opends.sdk.schema.Schema;
import com.sun.opends.sdk.util.FutureResultTransformer;
import com.sun.opends.sdk.util.Validator;
@@ -46,47 +46,20 @@
 * An heart beat connection factory can be used to create connections
 * that sends a periodic search request to a Directory Server.
 */
final class HeartBeatConnectionFactory extends
public class HeartBeatConnectionFactory extends
    AbstractConnectionFactory<AsynchronousConnection>
{
  private final SearchRequest heartBeat;
  private final long interval;
  private final int interval;
  private final List<AsynchronousConnectionImpl> activeConnections;
  private final ConnectionFactory<?> parentFactory;
  private volatile boolean stopRequested;
  // FIXME: use a single global scheduler?
  /**
   * Creates a new heart-beat connection factory which will create
   * connections using the provided connection factory and periodically
   * ping any created connections in order to detect that they are still
   * alive.
   *
   * @param connectionFactory
   *          The connection factory to use for creating connections.
   * @param timeout
   *          The time to wait between keepalive pings.
   * @param unit
   *          The time unit of the timeout argument.
   */
  HeartBeatConnectionFactory(ConnectionFactory<?> connectionFactory,
      long timeout, TimeUnit unit)
  {
    this(connectionFactory, timeout, unit, DEFAULT_SEARCH);
  }
  private static final SearchRequest DEFAULT_SEARCH = Requests
      .newSearchRequest("", SearchScope.BASE_OBJECT, "(objectClass=*)",
          "1.1");
  // FIXME: change timeout parameters to long+TimeUnit.
@@ -98,30 +71,18 @@
   *
   * @param connectionFactory
   *          The connection factory to use for creating connections.
   * @param timeout
   *          The time to wait between keepalive pings.
   * @param unit
   *          The time unit of the timeout argument.
   * @param heartBeat
   *          The search request to use when pinging connections.
   * @param interval
   *          The period between keepalive pings.
   */
  HeartBeatConnectionFactory(ConnectionFactory<?> connectionFactory,
      long timeout, TimeUnit unit, SearchRequest heartBeat)
  public HeartBeatConnectionFactory(
      ConnectionFactory<?> connectionFactory,
      int interval)
  {
    this.heartBeat = heartBeat;
    this.interval = unit.toMillis(timeout);
    Validator.ensureNotNull(connectionFactory);
    this.interval = interval;
    this.activeConnections = new LinkedList<AsynchronousConnectionImpl>();
    this.parentFactory = connectionFactory;
    Runtime.getRuntime().addShutdownHook(new Thread()
    {
      @Override
      public void run()
      {
        stopRequested = true;
      }
    });
    new HeartBeatThread().start();
  }
@@ -132,13 +93,11 @@
   * operations.
   */
  private final class AsynchronousConnectionImpl implements
      AsynchronousConnection, ConnectionEventListener,
      ResultHandler<Result>
      AsynchronousConnection, ConnectionEventListener
  {
    private final AsynchronousConnection connection;
    private AsynchronousConnectionImpl(AsynchronousConnection connection)
    {
      this.connection = connection;
@@ -352,7 +311,15 @@
      return connection.isClosed();
    }
    /**
     * {@inheritDoc}
     */
    public boolean isValid()
    {
      // Avoid extra pings... Let the next ping find out if this connection
      // is still valid.
      return connection.isValid();
    }
    public void connectionReceivedUnsolicitedNotification(
        GenericExtendedResult notification)
@@ -371,31 +338,6 @@
        activeConnections.remove(this);
      }
    }
    public void handleErrorResult(ErrorResultException error)
    {
      // TODO: I18N
      if (error instanceof TimeoutResultException)
      {
        close(Requests.newUnbindRequest(), "Heart beat timed out");
      }
    }
    public void handleResult(Result result)
    {
      // Do nothing
    }
    private void sendHeartBeat()
    {
      search(heartBeat, this, null);
    }
  }
@@ -405,19 +347,24 @@
    private HeartBeatThread()
    {
      super("Heart Beat Thread");
      this.setDaemon(true);
    }
    public void run()
    {
      while (!stopRequested)
      while(true)
      {
        synchronized (activeConnections)
        {
          for (AsynchronousConnectionImpl connection : activeConnections)
          {
            connection.sendHeartBeat();
            if(!connection.isValid())
            {
              connection.close(Requests.newUnbindRequest(),
                               "Connection no longer valid");
            }
          }
        }
        try