Alexey Goncharuk created IGNITE-14459:
-----------------------------------------
Summary: Affinity call may fail if called upon merged exchanges
Key: IGNITE-14459
URL:
https://issues.apache.org/jira/browse/IGNITE-14459 Project: Ignite
Issue Type: Improvement
Components: compute
Reporter: Alexey Goncharuk
When exchanges are merged, intermediate affinity assignments are not filled. At the same time, when a client chooses topology to run affinity call on, it may take a non-completed exchange version. As a result, when the affinity fetch task arrives on a node, it will look up a non-existing assignment, resulting in "Getting affinity for topology version earlier than affinity is calculated" exception.
{{CacheAffinityCallSelfTest.testAffinityCallNoServerNode}} is flaky because of this bug.
The following test case for {{CacheAffinityCallSelfTest}} demonstrates the issue:
{code}
/**
* @throws Exception if failed.
*/
@Test
public void testAffinityCallMergedExchanges() throws Exception {
startGrids(SRVS);
final Integer key = 1;
final IgniteEx client = startClientGrid(SRVS);
assertTrue(client.configuration().isClientMode());
assertNull(client.context().cache().cache(CACHE_NAME));
try {
grid(0).context().cache().context().exchange().mergeExchangesTestWaitVersion(
new AffinityTopologyVersion(SRVS + 3, 0),
null
);
IgniteInternalFuture<IgniteEx> fut1 = GridTestUtils.runAsync(() -> startGrid(SRVS + 1));
assertTrue(GridTestUtils.waitForCondition(() -> client.context().cache().context()
.exchange().lastTopologyFuture()
.initialVersion().equals(new AffinityTopologyVersion(SRVS + 2, 0)), 5_000));
assertFalse(fut1.isDone());
// The future should not complete until second node is started.
IgniteInternalFuture<Object> fut2 = GridTestUtils.runAsync(() ->
client.compute().affinityCall(CACHE_NAME, key, new CheckCallable(key, null)));
startGrid(SRVS + 2);
fut1.get();
fut2.get();
}
finally {
stopAllGrids();
}
}
{code}
--
This message was sent by Atlassian Jira
(v8.3.4#803005)