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)

Reply via email to