Class DSRSShutdownSync


  • public class DSRSShutdownSync
    extends Object
    Class useful for the case where DS/RS instances are collocated inside the same JVM. It synchronizes the shutdown of the DS and RS sides.

    More specifically, it ensures a ReplicaOfflineMsg sent by the DS is relayed/forwarded by the collocated RS to the other RSs in the topology before the whole process shuts down.

    The state is kept per domain and per instance: the collocated DS and RS sides coordinate through the single instance MultimasterReplication hands to both of them.

    Since:
    OPENDJ-1453
    • Field Summary

      Fields 
      Modifier and Type Field Description
      static long REPLICA_OFFLINE_GRACE_PERIOD
      How long a ReplicaOfflineMsg may hold back the shutdown of the collocated RS, in milliseconds, counted from the moment the message was announced.
    • Constructor Summary

      Constructors 
      Constructor Description
      DSRSShutdownSync()
      Creates a synchronization object using the default grace period.
    • Field Detail

      • REPLICA_OFFLINE_GRACE_PERIOD

        public static final long REPLICA_OFFLINE_GRACE_PERIOD
        How long a ReplicaOfflineMsg may hold back the shutdown of the collocated RS, in milliseconds, counted from the moment the message was announced.
        See Also:
        Constant Field Values
    • Constructor Detail

      • DSRSShutdownSync

        public DSRSShutdownSync()
        Creates a synchronization object using the default grace period.
    • Method Detail

      • replicaOfflineMsgSent

        public void replicaOfflineMsgSent​(DN baseDN,
                                          CSN offlineCSN)
        Message is about to be sent.

        The announcement comes before the message is published rather than after: a collocated replication server can forward the message as soon as it is on the wire, and a forward which finds nothing announced has nothing to clear. The announcement of a message the broker then refuses is taken back by replicaOfflineMsgNotSent(DN, CSN).

        A replica announces itself offline on every disableService(), so this may take the place of an earlier announcement of the same replica which is still owed its forward. The earlier one is kept behind the new one: a forward of the newer message, which the replication server queued behind the earlier one, covers both, and a withdrawal of the newer one gives the earlier one its wait back. It is kept only while its own grace period runs: past it, the announcement holds nothing back any more, and keeping it would chain every announcement of a replica whose message nobody in this process forwards - a directory server without a collocated replication server, or connected to a remote one - for the life of the process.

        Parameters:
        baseDN - the domain for which the message is being sent
        offlineCSN - the CSN of the message, which identifies both the replica which announces itself offline and the announcement being waited for
      • replicaOfflineMsgNotSent

        public void replicaOfflineMsgNotSent​(DN baseDN,
                                             CSN offlineCSN)
        The message which was announced was not sent after all: the broker had no session to write it to, or was stopped before it could.

        The announcement is made before the message is published, since a collocated replication server can forward it as soon as it is on the wire, so the announcement of a message the broker then refused has to be taken back: nobody will forward it, and the shutdown would spend the whole grace period waiting for that forward. Only the announcement carrying that CSN is withdrawn, and the announcement it displaced - an earlier message of the same replica which did go out and is still owed its forward - takes its place again.

        Whatever is reported about that earlier message while the announcement of the refused one stands in its place is not seen by it. A forward, or the loss of a peer it was queued for, is lost, and the shutdown then waits out what is left of the earlier message's own grace period; the peers it is queued for, if they are recorded in that window, are lost too, with the opposite effect - the first forward ends its wait, as for a message no peer was recorded for. That window is the one publish the broker refuses: at once on a connection error or a pending recovery, the broker's retry loop up to the reconnect when it has no session. The wait it can cost is bounded by a grace period which is already running.

        Parameters:
        baseDN - the domain for which the message was announced
        offlineCSN - the CSN of the message which was not sent
      • replicaOfflineMsgDispatched

        public void replicaOfflineMsgDispatched​(DN baseDN,
                                                CSN offlineCSN,
                                                Collection<Integer> replicationServerIds)
        Message has been queued for the replication servers which must forward it.

        This must be called before the message is queued for any of them: a replication server can forward it as soon as it is in its queue, and a forward which finds no recipient recorded ends the wait at once.

        Parameters:
        baseDN - the domain for which the message has been sent
        offlineCSN - the CSN of the message which is being queued
        replicationServerIds - the server ids of the replication servers the message is being queued for
      • replicaOfflineMsgForwarded

        public void replicaOfflineMsgForwarded​(DN baseDN,
                                               CSN forwardedCSN,
                                               int replicationServerId)
        Message has been forwarded to one of the replication servers it was queued for.
        Parameters:
        baseDN - the domain for which the message has been sent
        forwardedCSN - the CSN of the forwarded message
        replicationServerId - the server id of the replication server the message has been forwarded to
      • replicaOfflineMsgNotForwarded

        public void replicaOfflineMsgNotForwarded​(DN baseDN,
                                                  int replicationServerId)
        A replication server the message may have been queued for will not forward it: it is gone, or the message was dropped on its way out.

        Whatever it was given can no longer reach it, so the shutdown must not spend the rest of its grace period waiting for it.

        Parameters:
        baseDN - the domain the replication server is connected to
        replicationServerId - the server id of the replication server which will not forward the message
      • canShutdown

        public boolean canShutdown​(DN baseDN)
        Whether the shutdown of a domain can proceed, i.e. its ReplicaOfflineMsg has been forwarded by every replication server it was queued for, or its grace period has expired.

        The shutdown itself blocks on awaitReplicaOfflineMsgsForwarded(Collection, long) rather than polling this; it is the same state, observable without waiting for it.

        Parameters:
        baseDN - the baseDN of the domain being shut down
        Returns:
        true if the shutdown of this domain need not wait any longer, i.e. its message was forwarded or its grace period has expired, false otherwise
      • newShutdownDeadline

        public long newShutdownDeadline()
        Returns the time by which every wait of one shutdown must be over.

        A process shuts its domains down one after the other and each of them may have a message pending, so a deadline computed once and shared by all of them keeps the whole shutdown bounded by one grace period instead of one per domain.

        Returns:
        the point in time, on the System.nanoTime() clock, by which the waits must be over
      • awaitReplicaOfflineMsgsForwarded

        public void awaitReplicaOfflineMsgsForwarded​(Collection<DN> baseDNs,
                                                     long deadline)
        Waits for the ReplicaOfflineMsg of every provided domain to be forwarded, or for their grace periods or the provided deadline to expire.

        This must be called before the server handlers of those domains are stopped: stopping them deactivates their consumer, clears their message queue and closes their session, after which the message can no longer be forwarded.

        All the domains of one shutdown wait together rather than one after the other, so that the shutdown is bounded by one grace period without the wait of one domain spending the grace period of the next.

        Parameters:
        baseDNs - the baseDNs of the domains whose messages must be forwarded
        deadline - the point in time, on the System.nanoTime() clock, by which this wait must be over whatever the domains announce in the meantime - see newShutdownDeadline(). A deadline which is not in the future returns without waiting at all, for a caller which has nothing to wait for.