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

Valery Kharseko
13 hours ago 92d88ca699cd8090a26b92cbe46789d2b848195f
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/PendingChange.java
@@ -13,6 +13,7 @@
 *
 * Copyright 2006-2008 Sun Microsystems, Inc.
 * Portions copyright 2014-2016 ForgeRock AS.
 * Portions Copyright 2026 3A Systems, LLC.
 */
package org.opends.server.replication.plugin;
@@ -29,7 +30,29 @@
{
  private final CSN csn;
  private boolean committed;
  private UpdateMsg msg;
  /**
   * Written when the delivery which owns a remote change is taken over by the one which
   * follows it, and read by the dependency checks without the pending changes lock.
   */
  private volatile UpdateMsg msg;
  /**
   * Whether a replay thread owns this change: it is being replayed, or it waits for the
   * change it depends on. A remote change which no thread owns is one whose replay
   * failed and which the replication server is expected to deliver again.
   */
  private boolean owned;
  /**
   * How many times in a row the replay of this change failed, and when the first of
   * those failures happened - on a clock which only moves forward.
   * <p>
   * They live here, on the change which stays listed as the barrier holding the
   * ServerState back, rather than in a map on the side: a bound on such a map would have
   * a change evicted between two of its own failures and its give-up budget restarted,
   * so a replica failing more changes than the bound would never give up on any of them
   * (issue #889).
   */
  private int replayFailures;
  private long firstReplayFailureTimeMs;
  private final PluginOperation op;
  /**
@@ -108,6 +131,65 @@
  }
  /**
   * Returns whether a replay thread owns this change.
   *
   * @return {@code true} if a replay thread is replaying this change or waiting for the
   *         change it depends on
   */
  public boolean isOwned()
  {
    return owned;
  }
  /**
   * Sets whether a replay thread owns this change.
   *
   * @param owned {@code true} when a replay thread takes the change over, {@code false}
   *              when its replay failed and the change must be delivered again
   */
  public void setOwned(boolean owned)
  {
    this.owned = owned;
  }
  /**
   * Records that the replay of this change failed once more.
   *
   * @param nowMs
   *          when it failed, on a clock which only moves forward
   */
  public void recordReplayFailure(long nowMs)
  {
    if (replayFailures == 0)
    {
      firstReplayFailureTimeMs = nowMs;
    }
    replayFailures++;
  }
  /**
   * Returns how many times in a row the replay of this change failed.
   *
   * @return the number of failures, 0 when its replay never failed
   */
  public int getReplayFailures()
  {
    return replayFailures;
  }
  /**
   * Returns how long the replay of this change has been failing.
   *
   * @param nowMs
   *          the current time, on the clock {@link #recordReplayFailure(long)} was given
   * @return the duration in milliseconds, 0 when its replay never failed
   */
  public long getReplayFailingForMs(long nowMs)
  {
    return replayFailures == 0 ? 0 : nowMs - firstReplayFailureTimeMs;
  }
  /**
   * Get the operation associated to the PendingChange.
   * @return the operation
   */