0
# Event Handling
1
2
The Event Handling system provides comprehensive event support for cache operations with synchronous and asynchronous listeners, event filtering, and custom event dispatching. The `EventDispatcher` manages all cache entry events and their delivery to registered listeners.
3
4
## Capabilities
5
6
### EventDispatcher
7
8
Central component that manages and dispatches JCache events to registered listeners with support for different execution models.
9
10
```java { .api }
11
/**
12
* Manages and dispatches JCache events to registered listeners
13
*/
14
public final class EventDispatcher<K, V> {
15
16
/**
17
* Register a cache entry listener configuration
18
* @param cacheEntryListenerConfiguration the listener configuration to register
19
*/
20
public void register(CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration);
21
22
/**
23
* Deregister a cache entry listener configuration
24
* @param cacheEntryListenerConfiguration the listener configuration to remove
25
*/
26
public void deregister(CacheEntryListenerConfiguration<K, V> cacheEntryListenerConfiguration);
27
28
/**
29
* Publish entry created event to all registered listeners
30
* @param cache the cache where the event occurred
31
* @param key the key of the created entry
32
* @param value the value of the created entry
33
*/
34
public void publishCreated(Cache<K, V> cache, K key, V value);
35
36
/**
37
* Publish entry updated event to all registered listeners
38
* @param cache the cache where the event occurred
39
* @param key the key of the updated entry
40
* @param oldValue the previous value
41
* @param newValue the new value
42
*/
43
public void publishUpdated(Cache<K, V> cache, K key, V oldValue, V newValue);
44
45
/**
46
* Publish entry removed event to all registered listeners
47
* @param cache the cache where the event occurred
48
* @param key the key of the removed entry
49
* @param value the value of the removed entry
50
*/
51
public void publishRemoved(Cache<K, V> cache, K key, V value);
52
53
/**
54
* Publish entry removed event quietly (no error propagation)
55
* @param cache the cache where the event occurred
56
* @param key the key of the removed entry
57
* @param value the value of the removed entry
58
*/
59
public void publishRemovedQuietly(Cache<K, V> cache, K key, V value);
60
61
/**
62
* Publish entry expired event to all registered listeners
63
* @param cache the cache where the event occurred
64
* @param key the key of the expired entry
65
* @param value the value of the expired entry
66
*/
67
public void publishExpired(Cache<K, V> cache, K key, V value);
68
69
/**
70
* Publish entry expired event quietly (no error propagation)
71
* @param cache the cache where the event occurred
72
* @param key the key of the expired entry
73
* @param value the value of the expired entry
74
*/
75
public void publishExpiredQuietly(Cache<K, V> cache, K key, V value);
76
77
/**
78
* Wait for all synchronous listeners to complete processing
79
*/
80
public void awaitSynchronous();
81
82
/**
83
* Ignore completion of synchronous listeners (used during error handling)
84
*/
85
public void ignoreSynchronous();
86
87
/**
88
* Get all active listener registrations
89
* @return set of current registrations
90
*/
91
public Set<Registration<K, V>> registrations();
92
}
93
```
94
95
**Usage Examples:**
96
97
```java
98
Cache<String, String> cache = cacheManager.getCache("events", String.class, String.class);
99
100
// Create listener
101
CacheEntryListener<String, String> listener = new CacheEntryCreatedListener<String, String>() {
102
@Override
103
public void onCreated(Iterable<CacheEntryEvent<? extends String, ? extends String>> events) {
104
for (CacheEntryEvent<? extends String, ? extends String> event : events) {
105
System.out.println("Entry created: " + event.getKey() + " = " + event.getValue());
106
}
107
}
108
};
109
110
// Register listener
111
CacheEntryListenerConfiguration<String, String> listenerConfig =
112
new MutableCacheEntryListenerConfiguration<>(
113
FactoryBuilder.factoryOf(listener),
114
null, // No filter
115
false, // Not synchronous
116
true // Include old value
117
);
118
119
cache.registerCacheEntryListener(listenerConfig);
120
121
// Cache operations will trigger events
122
cache.put("key1", "value1"); // Triggers created event
123
cache.put("key1", "value2"); // Triggers updated event
124
cache.remove("key1"); // Triggers removed event
125
```
126
127
### Registration
128
129
Represents a registered cache entry listener with its configuration and filtering options.
130
131
```java { .api }
132
/**
133
* Represents a cache entry listener registration
134
*/
135
public final class Registration<K, V> {
136
137
/**
138
* Get the registered cache entry listener
139
* @return the CacheEntryListener instance
140
*/
141
public CacheEntryListener<? super K, ? super V> getCacheEntryListener();
142
143
/**
144
* Get the entry filter for this registration
145
* @return the CacheEntryFilter or null if none configured
146
*/
147
public CacheEntryFilter<? super K, ? super V> getCacheEntryFilter();
148
149
/**
150
* Get the original listener configuration
151
* @return the CacheEntryListenerConfiguration
152
*/
153
public CacheEntryListenerConfiguration<K, V> getConfiguration();
154
155
/**
156
* Check if this registration should receive events of the specified type
157
* @param eventType the event type to check
158
* @return true if this registration matches the event type
159
*/
160
public boolean matches(EventType eventType);
161
}
162
```
163
164
### Event Types and Listeners
165
166
Support for all JSR-107 event types with specific listener interfaces.
167
168
```java { .api }
169
// Event types
170
enum EventType {
171
CREATED, UPDATED, REMOVED, EXPIRED
172
}
173
174
// Listener interfaces
175
interface CacheEntryCreatedListener<K, V> extends CacheEntryListener<K, V> {
176
void onCreated(Iterable<CacheEntryEvent<? extends K, ? extends V>> events);
177
}
178
179
interface CacheEntryUpdatedListener<K, V> extends CacheEntryListener<K, V> {
180
void onUpdated(Iterable<CacheEntryEvent<? extends K, ? extends V>> events);
181
}
182
183
interface CacheEntryRemovedListener<K, V> extends CacheEntryListener<K, V> {
184
void onRemoved(Iterable<CacheEntryEvent<? extends K, ? extends V>> events);
185
}
186
187
interface CacheEntryExpiredListener<K, V> extends CacheEntryListener<K, V> {
188
void onExpired(Iterable<CacheEntryEvent<? extends K, ? extends V>> events);
189
}
190
```
191
192
**Usage Examples:**
193
194
```java
195
// Multi-event listener
196
CacheEntryListener<String, String> multiListener = new CacheEntryListener<String, String>()
197
implements CacheEntryCreatedListener<String, String>,
198
CacheEntryUpdatedListener<String, String>,
199
CacheEntryRemovedListener<String, String> {
200
201
@Override
202
public void onCreated(Iterable<CacheEntryEvent<? extends String, ? extends String>> events) {
203
events.forEach(event ->
204
System.out.println("Created: " + event.getKey() + " = " + event.getValue()));
205
}
206
207
@Override
208
public void onUpdated(Iterable<CacheEntryEvent<? extends String, ? extends String>> events) {
209
events.forEach(event ->
210
System.out.println("Updated: " + event.getKey() + " from " +
211
event.getOldValue() + " to " + event.getValue()));
212
}
213
214
@Override
215
public void onRemoved(Iterable<CacheEntryEvent<? extends String, ? extends String>> events) {
216
events.forEach(event ->
217
System.out.println("Removed: " + event.getKey() + " = " + event.getOldValue()));
218
}
219
};
220
```
221
222
### Event Filtering
223
224
Support for filtering events before delivery to listeners.
225
226
```java { .api }
227
/**
228
* Filter for cache entry events
229
*/
230
interface CacheEntryEventFilter<K, V> extends CacheEntryFilter<K, V> {
231
/**
232
* Evaluate whether an event should be delivered to the listener
233
* @param event the cache entry event
234
* @return true if the event should be delivered
235
*/
236
boolean evaluate(CacheEntryEvent<? extends K, ? extends V> event);
237
}
238
```
239
240
**Usage Examples:**
241
242
```java
243
// Filter to only receive events for keys starting with "user:"
244
CacheEntryEventFilter<String, String> userFilter = event ->
245
event.getKey().startsWith("user:");
246
247
// Register filtered listener
248
CacheEntryListenerConfiguration<String, String> filteredConfig =
249
new MutableCacheEntryListenerConfiguration<>(
250
FactoryBuilder.factoryOf(listener),
251
FactoryBuilder.factoryOf(userFilter),
252
false, // Not synchronous
253
true // Include old value
254
);
255
256
cache.registerCacheEntryListener(filteredConfig);
257
258
cache.put("user:123", "John"); // Event delivered (matches filter)
259
cache.put("session:456", "abc"); // Event filtered out
260
```
261
262
### Synchronous vs Asynchronous Listeners
263
264
Support for both synchronous and asynchronous event processing.
265
266
```java { .api }
267
// Synchronous listener configuration
268
CacheEntryListenerConfiguration<String, String> syncConfig =
269
new MutableCacheEntryListenerConfiguration<>(
270
FactoryBuilder.factoryOf(listener),
271
null,
272
true, // Synchronous execution
273
false
274
);
275
276
// Asynchronous listener configuration
277
CacheEntryListenerConfiguration<String, String> asyncConfig =
278
new MutableCacheEntryListenerConfiguration<>(
279
FactoryBuilder.factoryOf(listener),
280
null,
281
false, // Asynchronous execution
282
false
283
);
284
```
285
286
**Usage Examples:**
287
288
```java
289
// Synchronous listener for critical operations
290
CacheEntryListener<String, String> auditListener = new CacheEntryCreatedListener<String, String>() {
291
@Override
292
public void onCreated(Iterable<CacheEntryEvent<? extends String, ? extends String>> events) {
293
// Critical audit logging - must complete before cache operation returns
294
for (CacheEntryEvent<? extends String, ? extends String> event : events) {
295
auditLog.record("Cache entry created: " + event.getKey());
296
}
297
}
298
};
299
300
CacheEntryListenerConfiguration<String, String> auditConfig =
301
new MutableCacheEntryListenerConfiguration<>(
302
FactoryBuilder.factoryOf(auditListener),
303
null,
304
true, // Synchronous - blocks cache operation until complete
305
false
306
);
307
308
cache.registerCacheEntryListener(auditConfig);
309
310
// Asynchronous listener for notifications
311
CacheEntryListener<String, String> notificationListener = new CacheEntryCreatedListener<String, String>() {
312
@Override
313
public void onCreated(Iterable<CacheEntryEvent<? extends String, ? extends String>> events) {
314
// Send notifications asynchronously - doesn't block cache operations
315
CompletableFuture.runAsync(() -> {
316
for (CacheEntryEvent<? extends String, ? extends String> event : events) {
317
notificationService.sendNotification("New cache entry: " + event.getKey());
318
}
319
});
320
}
321
};
322
323
CacheEntryListenerConfiguration<String, String> notificationConfig =
324
new MutableCacheEntryListenerConfiguration<>(
325
FactoryBuilder.factoryOf(notificationListener),
326
null,
327
false, // Asynchronous - doesn't block cache operations
328
false
329
);
330
331
cache.registerCacheEntryListener(notificationConfig);
332
```
333
334
### JCacheEvictionListener
335
336
Bridge between Caffeine's removal events and JCache event system.
337
338
```java { .api }
339
/**
340
* Bridges Caffeine removal events to JCache event system
341
*/
342
public final class JCacheEvictionListener<K, V> implements RemovalListener<K, Expirable<V>> {
343
/**
344
* Handle removal notification from Caffeine cache
345
* @param key the removed key
346
* @param expirable the removed value wrapper
347
* @param cause the cause of removal
348
*/
349
@Override
350
public void onRemoval(K key, Expirable<V> expirable, RemovalCause cause);
351
}
352
```
353
354
### Event Configuration in Cache Creation
355
356
Configure event listeners during cache creation.
357
358
```java { .api }
359
// Configure listeners in cache configuration
360
CaffeineConfiguration<String, String> config = new CaffeineConfiguration<String, String>()
361
.setTypes(String.class, String.class)
362
.addCacheEntryListenerConfiguration(
363
new MutableCacheEntryListenerConfiguration<>(
364
FactoryBuilder.factoryOf(createdListener),
365
null, false, false))
366
.addCacheEntryListenerConfiguration(
367
new MutableCacheEntryListenerConfiguration<>(
368
FactoryBuilder.factoryOf(updatedListener),
369
FactoryBuilder.factoryOf(userFilter),
370
true, true));
371
372
Cache<String, String> cache = cacheManager.createCache("eventCache", config);
373
```
374
375
### Error Handling in Event Processing
376
377
Proper error handling for event processing failures.
378
379
```java { .api }
380
CacheEntryListener<String, String> errorHandlingListener = new CacheEntryCreatedListener<String, String>() {
381
@Override
382
public void onCreated(Iterable<CacheEntryEvent<? extends String, ? extends String>> events) {
383
for (CacheEntryEvent<? extends String, ? extends String> event : events) {
384
try {
385
processEvent(event);
386
} catch (Exception e) {
387
// Log error but don't let it propagate to cache operation
388
logger.error("Error processing cache event for key: " + event.getKey(), e);
389
}
390
}
391
}
392
393
private void processEvent(CacheEntryEvent<? extends String, ? extends String> event) {
394
// Event processing logic that might fail
395
}
396
};
397
```
398
399
### Event Batching
400
401
Events are delivered in batches for efficiency.
402
403
```java { .api }
404
CacheEntryListener<String, String> batchListener = new CacheEntryCreatedListener<String, String>() {
405
@Override
406
public void onCreated(Iterable<CacheEntryEvent<? extends String, ? extends String>> events) {
407
List<CacheEntryEvent<? extends String, ? extends String>> eventList =
408
StreamSupport.stream(events.spliterator(), false)
409
.collect(Collectors.toList());
410
411
System.out.println("Processing batch of " + eventList.size() + " events");
412
413
// Process all events in the batch
414
eventList.forEach(this::processEvent);
415
}
416
417
private void processEvent(CacheEntryEvent<? extends String, ? extends String> event) {
418
// Process single event
419
}
420
};
421
```