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

matthew_swift
21.17.2008 d696d8f9c4b425df6fbb2d523d7dc503745fcb72
Fix issue 2850.

Modify the LDAPClientConnection.cancelAllOperations(...) method to pre-emptively set a CancelResult in pending operations thus preventing the subsequent cancel request from blocking (this can cause very slow LDAP disconnects and potentially freeze the server). Fix a similar problem that can occur while shutting down the work queue.
11 files modified
108 ■■■■■ changed files
opends/src/server/org/opends/server/core/AddOperationBasis.java 7 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/BindOperationBasis.java 4 ●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/CompareOperationBasis.java 7 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/DeleteOperationBasis.java 7 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/ExtendedOperationBasis.java 7 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java 7 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/ModifyOperationBasis.java 7 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/SearchOperationBasis.java 5 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/UnbindOperationBasis.java 4 ●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/TraditionalWorkQueue.java 10 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java 43 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/core/AddOperationBasis.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 *      Portions Copyright 2007-2008 Sun Microsystems, Inc.
 */
package org.opends.server.core;
import org.opends.messages.Message;
@@ -570,11 +570,6 @@
                                     boolean sendNotification, Message message
  )
  {
    // Before calling clientConnection.disconnect, we need to mark this
    // operation as cancelled so that the attempt to cancel it later won't cause
    // an unnecessary delay.
    setCancelResult(CancelResult.CANCELED);
    clientConnection.disconnect(disconnectReason, sendNotification,
            message);
  }
opends/src/server/org/opends/server/core/BindOperationBasis.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 *      Portions Copyright 2007-2008 Sun Microsystems, Inc.
 */
package org.opends.server.core;
import org.opends.messages.Message;
@@ -555,8 +555,6 @@
                                     boolean sendNotification, Message message
  )
  {
    // Since bind operations can't be cancelled, we don't need to do anything
    // but forward the request on to the client connection.
    clientConnection.disconnect(disconnectReason, sendNotification,
            message);
  }
opends/src/server/org/opends/server/core/CompareOperationBasis.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 *      Portions Copyright 2007-2008 Sun Microsystems, Inc.
 */
package org.opends.server.core;
import org.opends.messages.Message;
@@ -291,11 +291,6 @@
                                     boolean sendNotification, Message message
  )
  {
    // Before calling clientConnection.disconnect, we need to mark this
    // operation as cancelled so that the attempt to cancel it later won't cause
    // an unnecessary delay.
    setCancelResult(CancelResult.CANCELED);
    clientConnection.disconnect(disconnectReason, sendNotification,
            message);
  }
opends/src/server/org/opends/server/core/DeleteOperationBasis.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 *      Portions Copyright 2007-2008 Sun Microsystems, Inc.
 */
package org.opends.server.core;
import org.opends.messages.Message;
@@ -243,11 +243,6 @@
                                     boolean sendNotification, Message message
  )
  {
    // Before calling clientConnection.disconnect, we need to mark this
    // operation as cancelled so that the attempt to cancel it later won't cause
    // an unnecessary delay.
    setCancelResult(CancelResult.CANCELED);
    clientConnection.disconnect(disconnectReason, sendNotification,
            message);
  }
opends/src/server/org/opends/server/core/ExtendedOperationBasis.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.opends.server.core;
import org.opends.messages.Message;
@@ -247,11 +247,6 @@
                                     boolean sendNotification, Message message
  )
  {
    // Before calling clientConnection.disconnect, we need to mark this
    // operation as cancelled so that the attempt to cancel it later won't cause
    // an unnecessary delay.
    setCancelResult(CancelResult.CANCELED);
    clientConnection.disconnect(disconnectReason, sendNotification,
            message);
  }
opends/src/server/org/opends/server/core/ModifyDNOperationBasis.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.opends.server.core;
import org.opends.messages.Message;
@@ -455,11 +455,6 @@
                                     boolean sendNotification, Message message
  )
  {
    // Before calling clientConnection.disconnect, we need to mark this
    // operation as cancelled so that the attempt to cancel it later won't cause
    // an unnecessary delay.
    setCancelResult(CancelResult.CANCELED);
    clientConnection.disconnect(disconnectReason, sendNotification,
            message);
  }
opends/src/server/org/opends/server/core/ModifyOperationBasis.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2007 Sun Microsystems, Inc.
 *      Portions Copyright 2007-2008 Sun Microsystems, Inc.
 */
package org.opends.server.core;
@@ -299,11 +299,6 @@
                                     boolean sendNotification, Message message
  )
  {
    // Before calling clientConnection.disconnect, we need to mark this
    // operation as cancelled so that the attempt to cancel it later won't cause
    // an unnecessary delay.
    setCancelResult(CancelResult.CANCELED);
    clientConnection.disconnect(disconnectReason, sendNotification,
            message);
  }
opends/src/server/org/opends/server/core/SearchOperationBasis.java
@@ -1175,11 +1175,6 @@
                                     boolean sendNotification, Message message
  )
  {
    // Before calling clientConnection.disconnect, we need to mark this
    // operation as cancelled so that the attempt to cancel it later won't cause
    // an unnecessary delay.
    setCancelResult(CancelResult.CANCELED);
    clientConnection.disconnect(disconnectReason, sendNotification, message);
  }
opends/src/server/org/opends/server/core/UnbindOperationBasis.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.opends.server.core;
import org.opends.messages.Message;
@@ -103,8 +103,6 @@
  public final void disconnectClient(DisconnectReason disconnectReason,
                                     boolean sendNotification, Message message)
  {
    // Since unbind operations can't be cancelled, we don't need to do anything
    // but forward the request on to the client connection.
    clientConnection.disconnect(disconnectReason, sendNotification,
            message);
  }
opends/src/server/org/opends/server/extensions/TraditionalWorkQueue.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.opends.server.extensions;
@@ -46,6 +46,7 @@
import org.opends.server.monitors.TraditionalWorkQueueMonitor;
import org.opends.server.types.AbstractOperation;
import org.opends.server.types.CancelRequest;
import org.opends.server.types.CancelResult;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DirectoryException;
@@ -227,7 +228,12 @@
    {
      try
      {
        o.cancel(cancelRequest);
        // The operation has no chance of responding to the cancel
        // request so avoid waiting for a cancel response.
        if (o.getCancelResult() == null) {
          o.setCancelResult(CancelResult.CANCELED);
          o.cancel(cancelRequest);
        }
      }
      catch (Exception e)
      {
opends/src/server/org/opends/server/protocols/ldap/LDAPClientConnection.java
@@ -22,7 +22,7 @@
 * CDDL HEADER END
 *
 *
 *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
 *      Portions Copyright 2006-2008 Sun Microsystems, Inc.
 */
package org.opends.server.protocols.ldap;
@@ -946,10 +946,18 @@
                         boolean sendNotification,
                         Message message)
  {
    // If we are already in the middle of a disconnect, then don't do anything.
    if (disconnectRequested)
    // Set a flag indicating that the connection is being terminated so that no
    // new requests will be accepted.  Also cancel all operations in progress.
    synchronized (opsInProgressLock)
    {
      return;
      // If we are already in the middle of a disconnect, then don't
      // do anything.
      if (disconnectRequested)
      {
        return;
      }
      disconnectRequested = true;
    }
@@ -968,23 +976,6 @@
    connectionValid = false;
    // Set a flag indicating that the connection is being terminated so that no
    // new requests will be accepted.  Also cancel all operations in progress.
    synchronized (opsInProgressLock)
    {
      try
      {
        disconnectRequested = true;
      }
      catch (Exception e)
      {
        if (debugEnabled())
        {
          TRACER.debugCaught(DebugLogLevel.ERROR, e);
        }
      }
    }
    cancelAllOperations(new CancelRequest(true, message));
    finalizeConnectionInternal();
@@ -1322,7 +1313,15 @@
        {
          try
          {
            CancelResult cancelResult = o.cancel(cancelRequest);
            CancelResult cancelResult = o.getCancelResult();
            if (cancelResult == null) {
              // Before calling cancelling the operation, we need to
              // mark this operation as cancelled so that the attempt to
              // cancel it later won't cause an unnecessary delay.
              o.setCancelResult(CancelResult.CANCELED);
              cancelResult = o.cancel(cancelRequest);
            }
            if (keepStats && (cancelResult == CancelResult.CANCELED))
            {
              statTracker.updateAbandonedOperation();