| | |
| | | * |
| | | * Copyright 2006-2008 Sun Microsystems, Inc. |
| | | * Portions copyright 2014-2016 ForgeRock AS. |
| | | * Portions Copyright 2026 3A Systems, LLC. |
| | | */ |
| | | package org.opends.server.replication.plugin; |
| | | |
| | |
| | | { |
| | | 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; |
| | | |
| | | /** |
| | |
| | | } |
| | | |
| | | /** |
| | | * 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 |
| | | */ |