0

I am following this doc: http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/distributed_regions/locking_in_global_regions.html to create a region with Global Scope to use distributed locking.

Cache.xml:

<client-cache>
<pool>…definition…</pool>
…
<!--region-attributes For Lock region-->
<region-attributes id="GZ_GLOBAL_REGION_LOCK_ATTRIBUTES" scope="global" pool-name="Zero"/>
…
</client-cache>

Code after GemFireCache created from gemfire.properties and cache.xml:

private Region<String, Object> getOrCreateLockRegion(GemFireCache gemfireCache) {
    Region<String, Object> region = gemfireCache.getRegion(lockRegionName);
    if (region == null) {
        if(!isUsingClientCache) {
            region = createRegionFactory((Cache)gemfireCache, String.class, Object.class, lockRegionAttributesID).create(lockRegionName);
        } else {
            region = createClientRegionFactory((ClientCache) gemfireCache, String.class, Object.class, lockRegionAttributesID).create(lockRegionName);
        }
    }
    return region;
}

protected <K, V> RegionFactory<K, V> createRegionFactory(Cache gemfireCache, Class<K> keyClass, Class<V> valueClass, String regionAttributeRefID) {
    return gemfireCache
            .<K, V>createRegionFactory(regionAttributeRefID)
            .setKeyConstraint(keyClass)
            .setValueConstraint(valueClass);
}

protected <K, V> ClientRegionFactory<K, V> createClientRegionFactory(ClientCache gemfireCache, Class<K> keyClass, Class<V> valueClass, String regionAttributeRefID) {
    return gemfireCache
            .<K, V>createClientRegionFactory(regionAttributeRefID)
            .setKeyConstraint(keyClass)
            .setValueConstraint(valueClass);
}

I suppose this will give me a region with Scope.Global, so that I can call region.getDistributedLock(“entrykey”); and then have the lock to coordinate between instances.

However, when I called getDistributedLock, I got a IllegalStateException: only supported for GLOBAL scope, not LOCAL

And I found out that the constructor of ClientRegionFactoryImpl force scope to Local no matter what configured in the region-attributes, and I don’t have API to overwrite it. This line: https://github.com/apache/incubator-geode/blob/develop/geode-core/src/main/java/org/apache/geode/cache/client/internal/ClientRegionFactoryImpl.java#L85

So the question is, am I supposed to use Distributed Lock from Client if I am using client – server DS configuration? If not, what should I do to make clients lock each other to synchronize when necessary?

Xiawei Zhang
  • 1,690
  • 1
  • 11
  • 24

1 Answers1

0

The DistributedLock and RegionDistributedLock APIs on the Region class are only available within the Server. In order to use these Locks from a Client, you would have to write Functions that you deploy to the Servers. The Client would then tell the Server to execute the Function where it can manipulate the Region as well as the DistributedLock and RegionDistributedLock APIs. More info on the FunctionService can be found at:

http://geode.apache.org/docs/guide/developing/function_exec/chapter_overview.html.

Kirk Lund
  • 106
  • 6
  • thanks for your answer Kirk. I saw the other thread asking more or less the same question too. what do you think about this approach: http://stackoverflow.com/a/40854854/2841265 ... Will "putIfAbsence" reliably and atomically update a entry from client side within a clustor? – Xiawei Zhang Nov 30 '16 at 01:44
  • Yeah, I like that solution. I haven't tried it, but it sounds like it should work. – Kirk Lund Nov 30 '16 at 01:47
  • I will try it out and update here once I get a chance – Xiawei Zhang Nov 30 '16 at 01:48