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

mrossign
19.31.2009 b6fb33af50bd7570ad0fa2c4441af20a907de4f3
Fix for issue #3887: Dynamic assured replication configuration change may give few timeouts

When doing a modrate on as DS where assured replication is not enabled,
if you enable assured replication (safe-data or safe-read) with dsconfig
at the same time, you may get some timeouts for some messages at the
beginning. This is due to the fact that new configuration values are set
(assured boolean set to true) before reconnection occurs. So messages
are fired in assured mode and then just after, the connection is broken
to reconnect with new configuration to the topology. This may make the
messages fired before reconnection fail in timeout.

Fix: read new conf, disconnect, store new conf, reconnect

1 files modified
42 ■■■■ changed files
opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java 42 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/replication/plugin/LDAPReplicationDomain.java
@@ -324,7 +324,7 @@
    this.updateToReplayQueue = updateToReplayQueue;
    // Get assured configuration
    readAssuredConfig(configuration);
    readAssuredConfig(configuration, false);
    setGroupId((byte)configuration.getGroupId());
    setURLs(configuration.getReferralsUrl());
@@ -408,17 +408,19 @@
   * a boolean indicating if the passed configuration has changed compared to
   * previous values and the changes require a reconnection.
   * @param configuration The configuration object
   * @return True if the assured configuration changed and we need to reconnect
   * @param allowReconnection Tells if one must reconnect if significant changes
   *        occurred
   */
  private boolean readAssuredConfig(ReplicationDomainCfg configuration)
  private void readAssuredConfig(ReplicationDomainCfg configuration,
    boolean allowReconnection)
  {
    boolean needReconnect = false;
    boolean needReconnection = false;
    byte newSdLevel = (byte) configuration.getAssuredSdLevel();
    if ((isAssured() && (getAssuredMode() == AssuredMode.SAFE_DATA_MODE)) &&
      (newSdLevel != getAssuredSdLevel()))
    {
      needReconnect = true;
      needReconnection = true;
    }
    AssuredType newAssuredType = configuration.getAssuredType();
@@ -427,25 +429,31 @@
      case NOT_ASSURED:
        if (isAssured())
        {
          needReconnect = true;
          needReconnection = true;
        }
        break;
      case SAFE_DATA:
        if (!isAssured() ||
          (isAssured() && (getAssuredMode() == AssuredMode.SAFE_READ_MODE)))
        {
          needReconnect = true;
          needReconnection = true;
        }
        break;
      case SAFE_READ:
        if (!isAssured() ||
          (isAssured() && (getAssuredMode() == AssuredMode.SAFE_DATA_MODE)))
        {
          needReconnect = true;
          needReconnection = true;
        }
        break;
    }
    // Disconnect if required: changing configuration values before
    // disconnection would make assured replication used immediately and
    // disconnection could cause some timeouts error.
    if (needReconnection && allowReconnection)
      disableService();
    switch (newAssuredType)
    {
      case NOT_ASSURED:
@@ -461,12 +469,11 @@
        break;
    }
    setAssuredSdLevel(newSdLevel);
    // Changing timeout does not require restart as it is not sent in
    // StartSessionMsg
    setAssuredTimeout(configuration.getAssuredTimeout());
    return needReconnect;
    // Reconnect if required
    if (needReconnection && allowReconnection)
      enableService();
  }
  /**
@@ -2729,15 +2736,8 @@
        configuration.getHeartbeatInterval(),
        (byte)configuration.getGroupId());
    // Get assured configuration
    boolean needReconnect = readAssuredConfig(configuration);
    // Reconnect if required
    if (needReconnect)
    {
      disableService();
      enableService();
    }
    // Read assured configuration and reconnect if needed
    readAssuredConfig(configuration, true);
    return new ConfigChangeResult(ResultCode.SUCCESS, false);
  }