Search in sources :

Example 1 with DistributedCacheOperation

use of org.apache.geode.internal.cache.DistributedCacheOperation in project geode by apache.

the class DistributedAckRegionCCEDUnitTest method testConcurrentOpWithGII.

/**
   * test for bug #45564. a create() is received by region creator and then a later destroy() is
   * received in initial image and while the version info from the destroy is recorded we keep the
   * value from the create event
   */
@Test
public void testConcurrentOpWithGII() {
    if (this.getClass() != DistributedAckRegionCCEDUnitTest.class) {
        // not really a scope-related thing
        return;
    }
    final String name = this.getUniqueName() + "-CC";
    final String key = "mykey";
    VM vm1 = Host.getHost(0).getVM(1);
    VM vm2 = Host.getHost(0).getVM(2);
    // create some destroyed entries so the GC service is populated
    SerializableCallable create = new SerializableCallable("create region") {

        public Object call() {
            RegionFactory f = getCache().createRegionFactory(getRegionAttributes());
            CCRegion = (LocalRegion) f.create(name);
            return CCRegion.getDistributionManager().getDistributionManagerId();
        }
    };
    // do conflicting update() and destroy() on the region. We want the update() to
    // be sent with a message and the destroy() to be transferred in the initial image
    // and be the value that we want to keep
    InternalDistributedMember vm1ID = (InternalDistributedMember) vm1.invoke(create);
    AsyncInvocation partialCreate = vm2.invokeAsync(new SerializableCallable("create region with stall") {

        public Object call() throws Exception {
            final GemFireCacheImpl cache = (GemFireCacheImpl) getCache();
            RegionFactory f = cache.createRegionFactory(getRegionAttributes());
            InitialImageOperation.VMOTION_DURING_GII = true;
            // this will stall region creation at the point of asking for an initial image
            VMotionObserverHolder.setInstance(new VMotionObserver() {

                @Override
                public void vMotionBeforeCQRegistration() {
                }

                @Override
                public void vMotionBeforeRegisterInterest() {
                }

                @Override
                public void vMotionDuringGII(Set recipientSet, LocalRegion region) {
                    InitialImageOperation.VMOTION_DURING_GII = false;
                    int oldLevel = LocalRegion.setThreadInitLevelRequirement(LocalRegion.BEFORE_INITIAL_IMAGE);
                    LocalRegion ccregion = cache.getRegionByPath("/" + name);
                    try {
                        // happen
                        while (!ccregion.isDestroyed() && ccregion.getRegionEntry(key) == null) {
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                return;
                            }
                        }
                    } finally {
                        LocalRegion.setThreadInitLevelRequirement(oldLevel);
                    }
                }
            });
            try {
                CCRegion = (LocalRegion) f.create(name);
                // at this point we should have received the update op and then the GII, which should
                // overwrite
                // the conflicting update op
                assertFalse("expected initial image transfer to destroy entry", CCRegion.containsKey(key));
            } finally {
                InitialImageOperation.VMOTION_DURING_GII = false;
            }
            return null;
        }
    });
    vm1.invoke(new SerializableRunnable("create conflicting events") {

        public void run() {
            // wait for the other to come on line
            long waitEnd = System.currentTimeMillis() + 45000;
            DistributionAdvisor adv = ((DistributedRegion) CCRegion).getCacheDistributionAdvisor();
            while (System.currentTimeMillis() < waitEnd && adv.adviseGeneric().isEmpty()) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    return;
                }
            }
            if (adv.adviseGeneric().isEmpty()) {
                fail("other member never came on line");
            }
            // inhibit all messaging
            DistributedCacheOperation.LOSS_SIMULATION_RATIO = 200.0;
            try {
                CCRegion.put("mykey", "initialValue");
                CCRegion.destroy("mykey");
            } finally {
                DistributedCacheOperation.LOSS_SIMULATION_RATIO = 0.0;
            }
            // generate a fake version tag for the message
            VersionTag tag = CCRegion.getRegionEntry(key).getVersionStamp().asVersionTag();
            // create a fake member ID that will be < mine and lose a concurrency check
            NetMember nm = CCRegion.getDistributionManager().getDistributionManagerId().getNetMember();
            InternalDistributedMember mbr = null;
            try {
                mbr = new InternalDistributedMember(nm.getInetAddress().getCanonicalHostName(), nm.getPort() - 1, "fake_id", "fake_id_ustring", DistributionManager.NORMAL_DM_TYPE, null, null);
                tag.setMemberID(mbr);
            } catch (UnknownHostException e) {
                org.apache.geode.test.dunit.Assert.fail("could not create member id", e);
            }
            // generate an event to distribute that contains the fake version tag
            EntryEventImpl event = EntryEventImpl.create(CCRegion, Operation.UPDATE, key, false, mbr, true, false);
            event.setNewValue("newValue");
            event.setVersionTag(tag);
            // this should update the controller's cache with the updated value but leave this cache
            // alone
            DistributedCacheOperation op = new UpdateOperation(event, tag.getVersionTimeStamp());
            op.distribute();
            event.release();
        }
    });
    try {
        partialCreate.getResult();
    } catch (Throwable e) {
        org.apache.geode.test.dunit.Assert.fail("async invocation in vm2 failed", e);
    }
}
Also used : DistributionAdvisor(org.apache.geode.distributed.internal.DistributionAdvisor) DistributedCacheOperation(org.apache.geode.internal.cache.DistributedCacheOperation) Set(java.util.Set) UnknownHostException(java.net.UnknownHostException) EntryEventImpl(org.apache.geode.internal.cache.EntryEventImpl) SerializableRunnable(org.apache.geode.test.dunit.SerializableRunnable) VMotionObserver(org.apache.geode.internal.cache.vmotion.VMotionObserver) LocalRegion(org.apache.geode.internal.cache.LocalRegion) AsyncInvocation(org.apache.geode.test.dunit.AsyncInvocation) RegionClearedException(org.apache.geode.internal.cache.RegionClearedException) UnknownHostException(java.net.UnknownHostException) CacheException(org.apache.geode.cache.CacheException) RegionFactory(org.apache.geode.cache.RegionFactory) InternalDistributedMember(org.apache.geode.distributed.internal.membership.InternalDistributedMember) UpdateOperation(org.apache.geode.internal.cache.UpdateOperation) VM(org.apache.geode.test.dunit.VM) SerializableCallable(org.apache.geode.test.dunit.SerializableCallable) VMVersionTag(org.apache.geode.internal.cache.versions.VMVersionTag) VersionTag(org.apache.geode.internal.cache.versions.VersionTag) GemFireCacheImpl(org.apache.geode.internal.cache.GemFireCacheImpl) NetMember(org.apache.geode.distributed.internal.membership.NetMember) FlakyTest(org.apache.geode.test.junit.categories.FlakyTest) Test(org.junit.Test) DistributedTest(org.apache.geode.test.junit.categories.DistributedTest)

Aggregations

UnknownHostException (java.net.UnknownHostException)1 Set (java.util.Set)1 CacheException (org.apache.geode.cache.CacheException)1 RegionFactory (org.apache.geode.cache.RegionFactory)1 DistributionAdvisor (org.apache.geode.distributed.internal.DistributionAdvisor)1 InternalDistributedMember (org.apache.geode.distributed.internal.membership.InternalDistributedMember)1 NetMember (org.apache.geode.distributed.internal.membership.NetMember)1 DistributedCacheOperation (org.apache.geode.internal.cache.DistributedCacheOperation)1 EntryEventImpl (org.apache.geode.internal.cache.EntryEventImpl)1 GemFireCacheImpl (org.apache.geode.internal.cache.GemFireCacheImpl)1 LocalRegion (org.apache.geode.internal.cache.LocalRegion)1 RegionClearedException (org.apache.geode.internal.cache.RegionClearedException)1 UpdateOperation (org.apache.geode.internal.cache.UpdateOperation)1 VMVersionTag (org.apache.geode.internal.cache.versions.VMVersionTag)1 VersionTag (org.apache.geode.internal.cache.versions.VersionTag)1 VMotionObserver (org.apache.geode.internal.cache.vmotion.VMotionObserver)1 AsyncInvocation (org.apache.geode.test.dunit.AsyncInvocation)1 SerializableCallable (org.apache.geode.test.dunit.SerializableCallable)1 SerializableRunnable (org.apache.geode.test.dunit.SerializableRunnable)1 VM (org.apache.geode.test.dunit.VM)1