[ 
https://issues.apache.org/jira/browse/GEODE-3232?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16090814#comment-16090814
 ] 

ASF GitHub Bot commented on GEODE-3232:
---------------------------------------

GitHub user upthewaterspout opened a pull request:

    https://github.com/apache/geode/pull/640

    GEODE-3232: Get a snapshot of maps when serializing FilterProfile

    Avoiding a race when serializing a CopyOnWrite data structures be
    grabbing a copy first.
    
    Thank you for submitting a contribution to Apache Geode.
    
    In order to streamline the review of the contribution we ask you
    to ensure the following steps have been taken:
    
    ### For all changes:
    - [ ] Is there a JIRA ticket associated with this PR? Is it referenced in 
the commit message?
    
    - [ ] Has your PR been rebased against the latest commit within the target 
branch (typically `develop`)?
    
    - [ ] Is your initial contribution a single, squashed commit?
    
    - [ ] Does `gradlew build` run cleanly?
    
    - [ ] Have you written or updated unit tests to verify your changes?
    
    - [ ] If adding new dependencies to the code, are these dependencies 
licensed in a way that is compatible for inclusion under [ASF 
2.0](http://www.apache.org/legal/resolved.html#category-a)?
    
    ### Note:
    Please ensure that once the PR is submitted, you check travis-ci for build 
issues and
    submit an update to your PR as soon as possible. If you need help, please 
send an
    email to d...@geode.apache.org.


You can merge this pull request into a Git repository by running:

    $ git pull https://github.com/upthewaterspout/incubator-geode 
feature/GEODE-3232

Alternatively you can review and apply these changes as the patch at:

    https://github.com/apache/geode/pull/640.patch

To close this pull request, make a commit to your master/trunk branch
with (at least) the following in the commit message:

    This closes #640
    
----
commit aaba2aae27c5b4f57d3bfba6220f6dfff60222f0
Author: Dan Smith <upthewatersp...@apache.org>
Date:   2017-07-17T23:46:19Z

    GEODE-3232: Get a snapshot of maps when serializing FilterProfile
    
    Avoiding a race when serializing a CopyOnWrite data structures be
    grabbing a copy first.

----


> Race condition serializing FilterProfile
> ----------------------------------------
>
>                 Key: GEODE-3232
>                 URL: https://issues.apache.org/jira/browse/GEODE-3232
>             Project: Geode
>          Issue Type: Bug
>          Components: client queues
>            Reporter: Dan Smith
>
> We saw an error we can't reproduce deserializing a FilterProfile.
> {noformat}
> [severe 2017/07/07 21:31:28.538 PDT 
> bridgegemfire4_rs-myFullRegr-client-23_13409 <P2P message reader for 
> rs-myFullRegr-client-23(bridgegemfire1_rs-myFullRegr-client-23_13408:13408)<ec><v7>:1025
>  shared unordered uid=3 port=56290> tid=0x5c] Error deserializing message
> org.apache.geode.SerializationException: Could not create an instance of  
> org.apache.geode.internal.cache.CreateRegionProcessor$CreateRegionReplyMessage
>  .
>         at 
> org.apache.geode.internal.InternalDataSerializer.invokeFromData(InternalDataSerializer.java:2381)
>         at 
> org.apache.geode.internal.DSFIDFactory.create(DSFIDFactory.java:981)
>         at 
> org.apache.geode.internal.InternalDataSerializer.readDSFID(InternalDataSerializer.java:2573)
>         at 
> org.apache.geode.internal.tcp.Connection.processNIOBuffer(Connection.java:3530)
>         at 
> org.apache.geode.internal.tcp.Connection.runNioReader(Connection.java:1814)
>         at org.apache.geode.internal.tcp.Connection.run(Connection.java:1675)
>         at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
>         at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
>         at java.lang.Thread.run(Thread.java:748)
> Caused by: org.apache.geode.SerializationException: Could not create an 
> instance of  
> org.apache.geode.internal.cache.partitioned.RegionAdvisor$PartitionProfile .
>         at 
> org.apache.geode.internal.InternalDataSerializer.invokeFromData(InternalDataSerializer.java:2381)
>         at 
> org.apache.geode.internal.DSFIDFactory.create(DSFIDFactory.java:981)
>         at 
> org.apache.geode.internal.InternalDataSerializer.basicReadObject(InternalDataSerializer.java:2691)
>         at 
> org.apache.geode.DataSerializer.readObject(DataSerializer.java:2961)
>         at 
> org.apache.geode.internal.cache.CreateRegionProcessor$CreateRegionReplyMessage.fromData(CreateRegionProcessor.java:798)
>         at 
> org.apache.geode.internal.InternalDataSerializer.invokeFromData(InternalDataSerializer.java:2370)
>         ... 8 more
> Caused by: org.apache.geode.SerializationException: Could not create an 
> instance of  org.apache.geode.internal.cache.FilterProfile .
>         at 
> org.apache.geode.internal.InternalDataSerializer.invokeFromData(InternalDataSerializer.java:2381)
>         at 
> org.apache.geode.internal.DSFIDFactory.create(DSFIDFactory.java:981)
>         at 
> org.apache.geode.internal.InternalDataSerializer.basicReadObject(InternalDataSerializer.java:2691)
>         at 
> org.apache.geode.DataSerializer.readObject(DataSerializer.java:2961)
>         at 
> org.apache.geode.internal.cache.CacheDistributionAdvisor$CacheProfile.fromData(CacheDistributionAdvisor.java:867)
>         at 
> org.apache.geode.internal.cache.partitioned.RegionAdvisor$PartitionProfile.fromData(RegionAdvisor.java:586)
>         at 
> org.apache.geode.internal.InternalDataSerializer.invokeFromData(InternalDataSerializer.java:2370)
>         ... 13 more
> Caused by: java.nio.BufferUnderflowException
>         at java.nio.Buffer.nextGetIndex(Buffer.java:506)
>         at java.nio.DirectByteBuffer.getInt(DirectByteBuffer.java:681)
>         at 
> org.apache.geode.internal.tcp.ByteBufferInputStream$ByteBufferByteSource.getInt(ByteBufferInputStream.java:267)
>         at 
> org.apache.geode.internal.tcp.ByteBufferInputStream.readInt(ByteBufferInputStream.java:963)
>         at 
> org.apache.geode.internal.InternalDataSerializer.readSetOfLongs(InternalDataSerializer.java:1775)
>         at 
> org.apache.geode.internal.cache.FilterProfile.fromData(FilterProfile.java:1469)
>         at 
> org.apache.geode.internal.InternalDataSerializer.invokeFromData(InternalDataSerializer.java:2370)
>         ... 19 more
> {noformat}
> From code inspection ,it looks like FilterProfile stores allKeyClients and 
> some other fields CopyOnWriteHashSets, which makes me think they can be 
> concurrently modified.
> However, FilterProfile.toData does this to write out this hash set.
> {code}
>     InternalDataSerializer.writeSetOfLongs(this.allKeyClients, 
> this.clientMap.hasLongID, out);
> {code}
> Within writeSetOfLongs, it first reads the size and writes it to the stream, 
> and then gets an iterator on the set. Between those two calls the set could 
> be modified.
> I think the code needs to do something like this for all of these sets to be 
> threadsafe:
> {code}
>     InternalDataSerializer.writeSetOfLongs(this.allKeyClients.getSnapshot(), 
> this.clientMap.hasLongID, out);
> {code}



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to