You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ignite.apache.org by "Aleksey Plekhanov (Jira)" <ji...@apache.org> on 2023/07/26 08:08:00 UTC

[jira] [Updated] (IGNITE-20038) [Thin Client] Cache operations with PA enabled can fail with BufferUnderflowException

     [ https://issues.apache.org/jira/browse/IGNITE-20038?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Aleksey Plekhanov updated IGNITE-20038:
---------------------------------------
    Affects Version/s: 2.15
                       2.14

> [Thin Client] Cache operations with PA enabled can fail with  BufferUnderflowException 
> ---------------------------------------------------------------------------------------
>
>                 Key: IGNITE-20038
>                 URL: https://issues.apache.org/jira/browse/IGNITE-20038
>             Project: Ignite
>          Issue Type: Task
>    Affects Versions: 2.14, 2.15
>         Environment: 
>            Reporter: Mikhail Petrov
>            Assignee: Mikhail Petrov
>            Priority: Major
>          Time Spent: 40m
>  Remaining Estimate: 0h
>
> Cache operations with PA enabled can fail on thin clients with  BufferUnderflowException due to broken ClientCachePartitionAwarenessGroup serialization.
> Exception: 
> {code:java}
>  java.nio.BufferUnderflowException
> 	at java.nio.Buffer.nextGetIndex(Buffer.java:532)
> 	at java.nio.HeapByteBuffer.getInt(HeapByteBuffer.java:366)
> 	at org.apache.ignite.internal.binary.streams.BinaryByteBufferInputStream.readInt(BinaryByteBufferInputStream.java:111)
> 	at org.apache.ignite.internal.binary.BinaryReaderExImpl.readInt(BinaryReaderExImpl.java:746)
> 	at org.apache.ignite.internal.client.thin.ClientCacheAffinityMapping.readCacheKeyConfiguration(ClientCacheAffinityMapping.java:240)
> 	at org.apache.ignite.internal.client.thin.ClientCacheAffinityMapping.readResponse(ClientCacheAffinityMapping.java:197)
> 	at org.apache.ignite.internal.client.thin.ClientCacheAffinityContext.readPartitionsUpdateResponse(ClientCacheAffinityContext.java:154)
> 	at org.apache.ignite.internal.client.thin.TcpClientChannel.receive(TcpClientChannel.java:412)
> 	at org.apache.ignite.internal.client.thin.TcpClientChannel.service(TcpClientChannel.java:311)
> 	at org.apache.ignite.internal.client.thin.ThinClientAbstractPartitionAwarenessTest$TestTcpClientChannel.service(ThinClientAbstractPartitionAwarenessTest.java:345)
> 	at org.apache.ignite.internal.client.thin.ReliableChannel.lambda$affinityInfoIsUpToDate$6(ReliableChannel.java:423)
> 	at org.apache.ignite.internal.client.thin.ReliableChannel.applyOnNodeChannel(ReliableChannel.java:746)
> 	at org.apache.ignite.internal.client.thin.ReliableChannel.affinityInfoIsUpToDate(ReliableChannel.java:422)
> 	at org.apache.ignite.internal.client.thin.ReliableChannel.affinityService(ReliableChannel.java:316)
> 	at org.apache.ignite.internal.client.thin.TcpClientCache.txAwareService(TcpClientCache.java:1139)
> 	at org.apache.ignite.internal.client.thin.TcpClientCache.cacheSingleKeyOperation(TcpClientCache.java:1198)
> 	at org.apache.ignite.internal.client.thin.TcpClientCache.get(TcpClientCache.java:146)
> 	at org.apache.ignite.internal.client.thin.ThinClientPartitionAwarenessStableTopologyTest.lambda$testMultipleCacheGroupPartitionsRequest$8(ThinClientPartitionAwarenessStableTopologyTest.java:250)
> 	at org.apache.ignite.testframework.GridTestUtils.lambda$runAsync$4(GridTestUtils.java:1229)
> 	at org.apache.ignite.testframework.GridTestUtils$7.call(GridTestUtils.java:1570)
> 	at org.apache.ignite.testframework.GridTestThread.run(GridTestThread.java:88)
> {code}
> Reproducer:
> {code:java}
> /** */
>     @Test
>     public void test() throws Exception {
>         Ignite ignite = startGrid(0);
>         ignite.createCache(new CacheConfiguration<>("test-cache-0").setCacheMode(REPLICATED));
>         ignite.createCache(new CacheConfiguration<>("test-cache-1").setCacheMode(PARTITIONED));
>         try (IgniteClient cli = Ignition.startClient(new ClientConfiguration().setAddresses("127.0.0.1:10800"))) {
>             ClientCacheAffinityContext affCtx = ((TcpIgniteClient)cli).reliableChannel().affinityContext();
>             IgniteInternalFuture<Object> replCacheOpFut;
>             IgniteInternalFuture<Object> partCacheOpFut;
>             synchronized (affCtx.cacheKeyMapperFactoryMap) {
>                 partCacheOpFut = GridTestUtils.runAsync(() -> cli.cache("test-cache-0").get(0));
>                 replCacheOpFut = GridTestUtils.runAsync(() -> cli.cache("test-cache-1").get(0));
>                 GridTestUtils.waitForCondition(
>                     () -> affCtx.pendingCacheIds.containsAll(F.transform(asList("test-cache-0", "test-cache-1"), CU::cacheId)),
>                     getTestTimeout()
>                 );
>             }
>             partCacheOpFut.get();
>             replCacheOpFut.get();
>         }
>     }
> {code}
> Explanation: 
> Take a look at the ClientCachePartitionAwarenessGroup#write method. During its serialization we write to the buffer the variable "dfltAffinity". Then take a look at ClientCacheAffinityMapping#readResponse. Here we deserialize the ClientCachePartitionAwarenessGroup instances, but in case the PA is not "applicable", we do not read the "dfltAffinity" variable from the buffer. As a result, if the ClientCacheAffinityMapping#readResponse deals with multiple cache group affinity mappings, the second one may not be properly deserialized due to the unread dfltAffinity variable .



--
This message was sent by Atlassian Jira
(v8.20.10#820010)