I'm using Ignite.NET 2.7.6. I did a very simple implementation of IAffinityFunction interface:
sealed class AffinityFunction : IAffinityFunction
{
public int Partitions { get { return 1; } }
public int GetPartition(object key) { return 0; }
public void RemoveNode(Guid nodeId) {}
public IEnumerable<IEnumerable<IClusterNode> > AssignPartitions(AffinityFunctionContext context)
{
List<IClusterNode> servers = new List<IClusterNode>();
foreach(IClusterNode node in context.CurrentTopologySnapshot)
{
if(!node.IsClient)
{
servers.Add(node);
}
}
m_Partitions = new List<IEnumerable<IClusterNode> >();
if(servers.Count != 0)
{
m_Partitions.Add(servers);
}
return m_Partitions;
}
private List<IEnumerable<IClusterNode> > m_Partitions;
}
Then I assign it to my cache's CacheConfiguration. I must mention that the cache is in the Replicated mode.
Firstly I start server node, then the client node and this leads to server crash with the following error in its log file:
java.lang.IndexOutOfBoundsException: index 0
at java.util.concurrent.atomic.AtomicReferenceArray.checkedByteOffset(Unknown Source)
at java.util.concurrent.atomic.AtomicReferenceArray.get(Unknown Source)
at org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopologyImpl.localPartition0(GridDhtPartitionTopologyImpl.java:911)
at org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopologyImpl.localPartition(GridDhtPartitionTopologyImpl.java:825)
As I understand this AffinityFunction must collect all the servers in one partition and returns this partition as the one to search in.
public int Partitions { get { return (m_Partitions != null ? m_Partitions.Count : 0); } }
0
is not a valid value for Partitions
property (should be positive)Partitions
property should return a constant value not based on any condition. This property is evaluated once per cache per node.The error message and documentation should be better, I'll file a ticket.