LDAPReplicationDomain.publishReplicaOfflineMsg()
(opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/LDAPReplicationDomain.java:1976-1980)
records the message as sent whether or not it was actually published:
public void publishReplicaOfflineMsg()
{
pendingChanges.putReplicaOfflineMsg();
dsrsShutdownSync.replicaOfflineMsgSent(getBaseDN(), getServerId());
}
putReplicaOfflineMsg() appends the message with a fresh CSN - therefore the newest one - and
calls pushCommittedChanges()
(opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/PendingChanges.java:127-136),
which walks the pending changes from the oldest and stops at the first uncommitted one:
while (firstChange != null && firstChange.isCommitted())
{
...
pendingChanges.remove(firstEntry.getKey());
...
}
So an operation still in flight when the domain is disabled leaves the ReplicaOfflineMsg
queued behind it, and domain.publish(msg) is never reached for it - while
replicaOfflineMsgSent() has already been recorded.
What it costs
Since #900 the record is the condition of a blocking wait: ReplicationServerDomain.shutdown()
calls awaitReplicaOfflineMsgForwarded() and, with a peer RS connected, waits the whole
remaining grace period (5 s per domain) for a message that never reached the wire. It is a
bounded delay of the shutdown, not a loss of data - the message stays in pendingChanges and
dies with the process.
Reporting the outcome of pushCommittedChanges() (or checking whether the offline change is
still pending) would let publishReplicaOfflineMsg() record only what it really sent.
Found while fixing #900, which leaves this path as it is.
LDAPReplicationDomain.publishReplicaOfflineMsg()(
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/LDAPReplicationDomain.java:1976-1980)records the message as sent whether or not it was actually published:
putReplicaOfflineMsg()appends the message with a fresh CSN - therefore the newest one - andcalls
pushCommittedChanges()(
opendj-server-legacy/src/main/java/org/opends/server/replication/plugin/PendingChanges.java:127-136),which walks the pending changes from the oldest and stops at the first uncommitted one:
So an operation still in flight when the domain is disabled leaves the
ReplicaOfflineMsgqueued behind it, and
domain.publish(msg)is never reached for it - whilereplicaOfflineMsgSent()has already been recorded.What it costs
Since #900 the record is the condition of a blocking wait:
ReplicationServerDomain.shutdown()calls
awaitReplicaOfflineMsgForwarded()and, with a peer RS connected, waits the wholeremaining grace period (5 s per domain) for a message that never reached the wire. It is a
bounded delay of the shutdown, not a loss of data - the message stays in
pendingChangesanddies with the process.
Reporting the outcome of
pushCommittedChanges()(or checking whether the offline change isstill pending) would let
publishReplicaOfflineMsg()record only what it really sent.Found while fixing #900, which leaves this path as it is.