blob: f9093a366ff1d1f31342fa1a173cd25a454181f2 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional information regarding
* copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License. You may obtain a
* copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.cache;
/**
* <p>
* A listener to handle region or entry related events.
* </p>
*
* <p>
* Instead of implementing this interface it is recommended that you extend the
* {@link org.apache.geode.cache.util.CacheListenerAdapter} class.
* </p>
*
* <h4>Avoiding the risk of deadlock</h4>
* <p>
* The methods on a <code>CacheListener</code> are invoked while holding a lock on the entry
* described by the {@link EntryEvent}, as a result if the listener method takes a long time to
* execute then it will cause the operation that caused it to be invoked to take a long time. In
* addition, listener code which calls {@link Region} methods could result in a deadlock. For
* example, in {@link #afterUpdate(EntryEvent)} for entry key k1, {@link Region#put(Object, Object)
* put(k2, someVal)} is called at the same time {@link #afterUpdate(EntryEvent)} for entry key k2
* calls {@link Region#put(Object, Object) put(k1, someVal)} a deadlock may result. This co-key
* dependency example can be extended to a co-Region dependency where listener code in Region "A"
* performs Region operations on "B" and listener code in Region "B" performs Region operations on
* "A". Deadlocks may be either java-level or distributed multi-VM dead locks depending on Region
* configuration. To be assured of no deadlocks, listener code should cause some other thread to
* access the region and must not wait for that thread to complete the task.
* </p>
*
* <p>
* WARNING: To avoid risk of deadlock, do not invoke CacheFactory.getAnyInstance() from within any
* callback methods. Instead use EntryEvent.getRegion().getCache() or
* RegionEvent.getRegion().getCache().
* </p>
*
* <h4>Concurrency</h4>
* <p>
* Multiple events, on different entries, can cause concurrent invocation of
* <code>CacheListener</code> methods. Any exceptions thrown by the listener are caught by GemFire
* and logged.
* </p>
*
* <h4>Declaring instances in Cache XML files</h4>
* <p>
* To declare a CacheListener in a Cache XML file, it must also implement {@link Declarable}
* </p>
*
* @see AttributesFactory#addCacheListener
* @see AttributesFactory#initCacheListeners
* @see RegionAttributes#getCacheListeners
* @see AttributesMutator#addCacheListener
* @see AttributesMutator#removeCacheListener
* @see AttributesMutator#initCacheListeners
* @since GemFire 3.0
*/
public interface CacheListener<K, V> extends CacheCallback {
/**
* Handles the event of new key being added to a region. The entry did not previously exist in
* this region in the local cache (even with a null value).
*
* @param event the EntryEvent
* @see Region#create(Object, Object)
* @see Region#put(Object, Object)
* @see Region#get(Object)
*/
void afterCreate(EntryEvent<K, V> event);
/**
* Handles the event of an entry's value being modified in a region. This entry previously existed
* in this region in the local cache, but its previous value may have been null.
*
* @param event the EntryEvent
* @see Region#put(Object, Object)
*/
void afterUpdate(EntryEvent<K, V> event);
/**
* Handles the event of an entry's value being invalidated.
*
* @param event the EntryEvent
* @see Region#invalidate(Object)
*/
void afterInvalidate(EntryEvent<K, V> event);
/**
* Handles the event of an entry being destroyed.
*
* @param event the EntryEvent
* @see Region#destroy(Object)
*/
void afterDestroy(EntryEvent<K, V> event);
/**
* Handles the event of a region being invalidated. Events are not invoked for each individual
* value that is invalidated as a result of the region being invalidated. Each subregion, however,
* gets its own <code>regionInvalidated</code> event invoked on its listener.
*
* @param event the RegionEvent
* @see Region#invalidateRegion()
* @see Region#localInvalidateRegion()
*/
void afterRegionInvalidate(RegionEvent<K, V> event);
/**
* Handles the event of a region being destroyed. Events are not invoked for each individual entry
* that is destroyed as a result of the region being destroyed. Each subregion, however, gets its
* own <code>afterRegionDestroyed</code> event invoked on its listener.
*
* @param event the RegionEvent
* @see Region#destroyRegion()
* @see Region#localDestroyRegion()
* @see Region#close
* @see Cache#close()
*/
void afterRegionDestroy(RegionEvent<K, V> event);
/**
* Handles the event of a region being cleared. Events are not invoked for each individual entry
* that is removed as a result of the region being cleared.
*
* @param event the RegionEvent
*
* @see Region#clear
* @since GemFire 5.0
*/
void afterRegionClear(RegionEvent<K, V> event);
/**
* Handles the event of a region being created. Events are invoked for each individual region that
* is created.
* <p>
* Note that this method is only called for creates done in the local vm. To be notified of
* creates done in remote vms use {@link RegionMembershipListener#afterRemoteRegionCreate}.
*
* @param event the RegionEvent
*
* @see Cache#createRegion
* @see Region#createSubregion
* @since GemFire 5.0
*/
void afterRegionCreate(RegionEvent<K, V> event);
/**
* Handles the event of a region being live after receiving the marker from the server.
*
* @param event the RegionEvent
*
* @see Cache#readyForEvents
* @since GemFire 5.5
*/
void afterRegionLive(RegionEvent<K, V> event);
}