mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
HCOLL-246 Fixed - Tcp Replication fails with large values or entries sizes that don't included internal replication bytes"
This commit is contained in:
@@ -30,39 +30,43 @@ import java.io.Closeable;
|
||||
interface Replica extends Closeable {
|
||||
|
||||
/**
|
||||
* Provides the unique Identifier associated with this map instance. <p> An identifier is used to
|
||||
* determine which replicating node made the change. <p> If two nodes update their map at the same time
|
||||
* with different values, we have to deterministically resolve which update wins, because of eventual
|
||||
* consistency both nodes should end up locally holding the same data. Although it is rare two remote
|
||||
* nodes could receive an update to their maps at exactly the same time for the same key, we have to
|
||||
* handle this edge case, its therefore important not to rely on timestamps alone to reconcile the
|
||||
* updates. Typically the update with the newest timestamp should win, but in this example both
|
||||
* timestamps are the same, and the decision made to one node should be identical to the decision made to
|
||||
* the other. We resolve this simple dilemma by using a node identifier, each node will have a unique
|
||||
* identifier, the update from the node with the smallest identifier wins.
|
||||
* Provides the unique Identifier associated with this map instance. <p> An identifier is used
|
||||
* to determine which replicating node made the change. <p> If two nodes update their map at the
|
||||
* same time with different values, we have to deterministically resolve which update wins,
|
||||
* because of eventual consistency both nodes should end up locally holding the same data.
|
||||
* Although it is rare two remote nodes could receive an update to their maps at exactly the
|
||||
* same time for the same key, we have to handle this edge case, its therefore important not to
|
||||
* rely on timestamps alone to reconcile the updates. Typically the update with the newest
|
||||
* timestamp should win, but in this example both timestamps are the same, and the decision
|
||||
* made to one node should be identical to the decision made to the other. We resolve this
|
||||
* simple dilemma by using a node identifier, each node will have a unique identifier, the
|
||||
* update from the node with the smallest identifier wins.
|
||||
*
|
||||
* @return the unique Identifier associated with this map instance
|
||||
*/
|
||||
byte identifier();
|
||||
|
||||
/**
|
||||
* Gets (if it does not exist, creates) an instance of ModificationIterator associated with a remote node,
|
||||
* this weak associated is bound using the {@code identifier}.
|
||||
* Gets (if it does not exist, creates) an instance of ModificationIterator associated with a
|
||||
* remote node, this weak associated is bound using the {@code identifier}.
|
||||
*
|
||||
* @param remoteIdentifier the identifier of the remote node
|
||||
* @param modificationNotifier called when ever there is a change applied to the modification iterator
|
||||
* @return the ModificationIterator dedicated for replication to the remote node with the given identifier
|
||||
* @param modificationNotifier called when ever there is a change applied to the modification
|
||||
* iterator
|
||||
* @return the ModificationIterator dedicated for replication to the remote node with the given
|
||||
* identifier
|
||||
* @see #identifier()
|
||||
*/
|
||||
ModificationIterator acquireModificationIterator(byte remoteIdentifier,
|
||||
ModificationNotifier modificationNotifier);
|
||||
|
||||
/**
|
||||
* Returns the timestamp of the last change from the specified remote node, already replicated to this
|
||||
* Replica. <p>Used in conjunction with replication, to back fill data from a remote node. This node
|
||||
* may have missed updates while it was not been running or connected via TCP.
|
||||
* Returns the timestamp of the last change from the specified remote node, already replicated
|
||||
* to this Replica. <p>Used in conjunction with replication, to back fill data from a remote
|
||||
* node. This node may have missed updates while it was not been running or connected via TCP.
|
||||
*
|
||||
* @param remoteIdentifier the identifier of the remote node to check last replicated update time from
|
||||
* @param remoteIdentifier the identifier of the remote node to check last replicated update
|
||||
* time from
|
||||
* @return a timestamp of the last modification to an entry, or 0 if there are no entries.
|
||||
* @see #identifier()
|
||||
*/
|
||||
@@ -97,20 +101,21 @@ interface Replica extends Closeable {
|
||||
boolean hasNext();
|
||||
|
||||
/**
|
||||
* A non-blocking call that provides the entry that has changed to {@code callback.onEntry()}.
|
||||
* A non-blocking call that provides the entry that has changed to {@code
|
||||
* callback.onEntry()}.
|
||||
*
|
||||
* @param callback a callback which will be called when a new entry becomes available.
|
||||
* @param chronicleId only assigned when using chronicle channels
|
||||
* @return {@code true} if the entry was accepted by the {@code callback.onEntry()} method, {@code
|
||||
* false} if the entry was not accepted or was not available
|
||||
* @return {@code true} if the entry was accepted by the {@code callback.onEntry()} method,
|
||||
* {@code false} if the entry was not accepted or was not available
|
||||
*/
|
||||
boolean nextEntry(@NotNull final EntryCallback callback, final int chronicleId);
|
||||
|
||||
/**
|
||||
* Dirties all entries with a modification time equal to {@code fromTimeStamp} or newer. It means all
|
||||
* these entries will be considered as "new" by this ModificationIterator and iterated once again no
|
||||
* matter if they have already been. <p>This functionality is used to publish recently modified
|
||||
* entries to a new remote node as it connects.
|
||||
* Dirties all entries with a modification time equal to {@code fromTimeStamp} or newer. It
|
||||
* means all these entries will be considered as "new" by this ModificationIterator and
|
||||
* iterated once again no matter if they have already been. <p>This functionality is used
|
||||
* to publish recently modified entries to a new remote node as it connects.
|
||||
*
|
||||
* @param fromTimeStamp the timestamp from which all entries should be dirty
|
||||
*/
|
||||
@@ -122,25 +127,35 @@ interface Replica extends Closeable {
|
||||
*/
|
||||
interface EntryExternalizable {
|
||||
|
||||
/**
|
||||
* @param entry an entry in the map
|
||||
* @param chronicleId is the channel id used to identify the canonical map or queue
|
||||
* @return the size of the entry
|
||||
*/
|
||||
int sizeOfEntry(@NotNull Bytes entry, int chronicleId);
|
||||
|
||||
/**
|
||||
* The map implements this method to save its contents.
|
||||
*
|
||||
* @param entry the byte location of the entry to be stored
|
||||
* @param destination a buffer the entry will be written to, the segment may reject this operation and
|
||||
* add zeroBytes, if the identifier in the entry did not match the maps local
|
||||
* @param destination a buffer the entry will be written to, the segment may reject this
|
||||
* operation and add zeroBytes, if the identifier in the entry did not
|
||||
* match the maps local
|
||||
* @param chronicleId is the channel id used to identify the canonical map or queue
|
||||
*/
|
||||
void writeExternalEntry(@NotNull Bytes entry, @NotNull Bytes destination, int chronicleId);
|
||||
void writeExternalEntry(@NotNull Bytes entry, @NotNull Bytes destination, int
|
||||
chronicleId);
|
||||
|
||||
/**
|
||||
* The map implements this method to restore its contents. This method must read the values in the
|
||||
* same sequence and with the same types as were written by {@code writeExternalEntry()}. This method
|
||||
* is typically called when we receive a remote replication event, this event could originate from
|
||||
* either a remote {@code put(K key, V value)} or {@code remove(Object key)}
|
||||
* The map implements this method to restore its contents. This method must read the values
|
||||
* in the same sequence and with the same types as were written by {@code
|
||||
* writeExternalEntry()}. This method is typically called when we receive a remote
|
||||
* replication event, this event could originate from either a remote {@code put(K key, V
|
||||
*value)} or {@code remove(Object key)}
|
||||
*
|
||||
* @param copies
|
||||
* @param segmentState
|
||||
* @param source bytes to read an entry from
|
||||
* @param source bytes to read an entry from
|
||||
*/
|
||||
void readExternalEntry(
|
||||
@NotNull ThreadLocalCopies copies,
|
||||
@@ -148,8 +163,8 @@ interface Replica extends Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* provides a key and value from NativeBytes, this can be used in conjunction with the modification
|
||||
* iterator to get the key and value out of the NativeBytes
|
||||
* provides a key and value from NativeBytes, this can be used in conjunction with the
|
||||
* modification iterator to get the key and value out of the NativeBytes
|
||||
*/
|
||||
interface EntryResolver<K, V> {
|
||||
|
||||
@@ -175,20 +190,20 @@ interface Replica extends Closeable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implemented typically by a replicator, This interface provides the event, which will get called
|
||||
* whenever a put() or remove() has occurred to the map
|
||||
* Implemented typically by a replicator, This interface provides the event, which will get
|
||||
* called whenever a put() or remove() has occurred to the map
|
||||
*/
|
||||
abstract class EntryCallback {
|
||||
|
||||
/**
|
||||
* Called whenever a put() or remove() has occurred to a replicating map.
|
||||
*
|
||||
* @param entry the entry you will receive, this does not have to be locked, as locking is
|
||||
* already provided from the caller.
|
||||
* @param entry the entry you will receive, this does not have to be locked, as
|
||||
* locking is already provided from the caller.
|
||||
* @param chronicleId only assigned when clustering
|
||||
* @return {@code false} if this entry should be ignored because the identifier of the source node is
|
||||
* not from one of our changes, WARNING even though we check the identifier in the
|
||||
* ModificationIterator the entry may have been updated.
|
||||
* @return {@code false} if this entry should be ignored because the identifier of the
|
||||
* source node is not from one of our changes, WARNING even though we check the identifier
|
||||
* in the ModificationIterator the entry may have been updated.
|
||||
*/
|
||||
public abstract boolean onEntry(final Bytes entry, final int chronicleId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user