Implementing Delta Propagation
Implementing Delta Propagation
By default, delta propagation is enabled in your distributed system. When enabled, delta propagation is used for objects that implement com.gemstone.gemfire.Delta. You program the methods to store and extract delta information for your entries and to apply received delta information.
- Study your object types and expected application behavior to determine which regions can benefit from using delta propagation. Delta propagation does not improve performance for all data and data modification scenarios. See When to Avoid Delta Propagation.
- For each region where you are using delta propagation, choose whether to enable cloning using the delta propagation property cloning-enabled. Cloning is disabled by default. See Delta Propagation Properties.
- If you do not enable cloning, review all associated listener code for dependencies on EntryEvent.getOldValue. Without cloning, GemFire modifies the entry in place and so loses its reference to the old value. For delta events, the EntryEvent methods getOldValue and getNewValue both return the new value.
- For every class where you want
delta propagation, implement com.gemstone.gemfire.Delta and
update your methods to support delta propagation. Exactly how you do this
depends on your application and object needs, but these steps describe the
- If the class is a plain old Java object (POJO), wrap it for this implementation and update your code to work with the wrapper class.
- Define as transient any extra object fields that you use to manage delta state. This can help performance when the full object is distributed. Whenever standard Java serialization is used, the transient keyword indicates to Java to not serialize the field.
- Study the object contents to decide how to handle delta changes. Delta propagation has the same issues of distributed concurrency control as the distribution of full objects, but on a more detailed level. Some parts of your objects may be able to change independent of one another while others may always need to change together. Send deltas large enough to keep your data logically consistent. If, for example, field A and field B depend on each other, then your delta distributions should either update both fields or neither. As with regular updates, the fewer producers you have on a data region, the lower your likelihood of concurrency issues.
- In the application code that puts entries, put the fully populated object into the local cache. Even though you are planning to send only deltas, errors on the receiving end could cause GemFire to request the full object, so you must provide it to the originating put method. Do this even in empty producers, with regions configured for no local data storage. This usually means doing a get on the entry unless you are sure it does not already exist anywhere in the distributed region.
- Change each field's update method to record information about the update. The information must be sufficient for toDelta to encode the delta and any additional required delta information when it is invoked.
- Write hasDelta to report on whether a delta is available.
- Write toDelta to create a byte stream with the changes to the object and any other information fromDelta will need to apply the changes. Before returning from toDelta, reset your delta state to indicate that there are no delta changes waiting to be sent.
- Write fromDelta to decode the byte stream that toDelta creates and update the object.
- Make sure you provide adequate synchronization to your object to maintain a consistent object state. If you do not use cloning, you will probably need to synchronize on reads and writes to avoid reading partially written updates from the cache.This synchronization might involve toDelta, fromDelta, toData, fromData, and other methods that access or update the object. Additionally, your implementation should take into account the possibility of concurrent invocations of fromDelta and one or more of the object's update methods.