Apache Geode CHANGELOG

Resolving Conflicting Events

You can optionally create a GatewayConflictResolver cache plug-in to decide whether a potentially conflicting event that was delivered from another site should be applied to the local cache.

By default, all regions perform consistency checks when a member applies an update received either from another cluster member or from a remote cluster over the WAN. The default consistency checking for WAN events is described in How Consistency Is Achieved in WAN Deployments.

You can override the default consistency checking behavior by writing and configuring a custom GatewayConflictResolver. The GatewayConflictResolver implementation can use the timestamp and distributed system ID included in a WAN update event to determine whether or not to apply the update. For example, you may decide that updates from a particular cluster should always “win” a conflict when the timestamp difference between updates is less than some fixed period of time.

Implementing a GatewayConflictResolver

Note: A GatewayConflictResolver implementation is called only for update events that could cause a conflict in the region. This corresponds to update events that have a different distributed system ID than the distributed system that last updated the region entry. If the same distributed system ID makes consecutive updates to a region entry, no conflict is possible, and the GatewayConflictResolver is not called.

Procedure

  1. Program the event handler:

    1. Create a class that implements the GatewayConflictResolver interface.
    2. If you want to declare the handler in cache.xml, implement the org.apache.geode.cache.Declarable interface as well.
    3. Implement the handler’s onEvent() method to determine whether the WAN event should be allowed. onEvent() receives both a TimestampedEntryEvent and a GatewayConflictHelper instance. TimestampedEntryEvent has methods for obtaining the timestamp and distributed system ID of both the update event and the current region entry. Use methods in the GatewayConflictHelper to either disallow the update event (retaining the existing region entry value) or provide an alternate value.

      Example:

       public void onEvent(TimestampedEntryEvent event, GatewayConflictHelper helper) {
          if (event.getOperation().isUpdate()) {
            ShoppingCart oldCart = (ShoppingCart)event.getOldValue();
            ShoppingCart newCart = (ShoppingCart)event.getNewValue();
            oldCart.updateFromConflictingState(newCart);
            helper.changeEventValue(oldCart);
          }
        }
      

      Note: In order to maintain consistency in the region, your conflict resolver must always resolve two events in the same way regardless of which event it receives first.

  2. Install the conflict resolver for the cache, using either the cache.xml file or the Java API.

    cache.xml

    <cache>
         ... 
        <gateway-conflict-resolver>
          <class-name>myPackage.MyConflictResolver</class-name>
        </gateway-conflict-resolver>
        ...
    </cache>
    

    Java API

    // Create or obtain the cache
    Cache cache = new CacheFactory().create();
    
    // Create and add a conflict resolver
    cache.setGatewayConflictResolver(new MyConflictResolver);