From 5154f34503981b2f96755b1b6da9b425bb20ca7f Mon Sep 17 00:00:00 2001
From: Valery Kharseko <vharseko@3a-systems.ru>
Date: Thu, 05 Nov 2026 14:32:12 +0000
Subject: [PATCH] [#1269] Preserve replay order across duplicate replication deliveries (#1270)
---
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/UpdateToReplay.java | 37 +++++++++++++++++++++++++++++++------
1 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/UpdateToReplay.java b/opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/UpdateToReplay.java
index 3919dd6..6fdf659 100644
--- a/opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/UpdateToReplay.java
+++ b/opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/UpdateToReplay.java
@@ -13,21 +13,22 @@
*
* Copyright 2006-2008 Sun Microsystems, Inc.
* Portions Copyright 2015 ForgeRock AS.
+ * Portions Copyright 2026 3A Systems, LLC.
*/
package org.opends.server.replication.plugin;
import org.opends.server.replication.protocol.LDAPUpdateMsg;
/**
- * This is a bag class to hold an update to replay in the queue of updates to
- * be replayed by the replay threads.
- * It associates an update message to replay with the matching
- * ReplicationDomain.
+ * A delivery in the shared replay queue, associating an update with its domain.
+ * Cancellation belongs to this delivery, so an enqueue or claim failure can release
+ * it without acquiring the pending-changes lock or cancelling a newer retry.
*/
public class UpdateToReplay
{
- private LDAPUpdateMsg updateMessage;
- private LDAPReplicationDomain replicationDomain;
+ private final LDAPUpdateMsg updateMessage;
+ private final LDAPReplicationDomain replicationDomain;
+ private volatile boolean cancelled;
/**
* Construct the object associating the update message with the replication
@@ -44,6 +45,30 @@
}
/**
+ * Releases a failed hand-off without a lock or allocation, even on an OOME road.
+ * A stale cancellation affects only this delivery, never the retry which replaced it.
+ */
+ void cancel()
+ {
+ cancel(true);
+ }
+
+ /** Cancels this delivery, optionally requesting another session. */
+ void cancel(boolean requestRestart)
+ {
+ cancelled = true;
+ if (requestRestart && replicationDomain != null)
+ {
+ replicationDomain.requestSessionRestart();
+ }
+ }
+
+ boolean isCancelled()
+ {
+ return cancelled;
+ }
+
+ /**
* Getter for update message.
* @return The update message
*/
--
Gitblit v1.10.0