== Who Am I?
Romain Manni-Bucau
image::img/twitter.png[]
image::img/wordpress.png[]
image::img/github.png[]
image::img/tomitribe.png[]
== What is Apache JCS?
- Distributed (or not) caching system written in Java
- Built @Apache
- Designed for high read, low put applications.
== JCS Core Concepts
- Elements: a cached object
- Regions: a cache subpart (with its own configuration)
- Auxilaries: plugins
== JCS Configuration
Properties based
[source,bash,numbered]
----
jcs.default = DC
jcs.default.cacheattributes = org.apache.commons.jcs.engine.CompositeCacheAttributes
jcs.default.cacheattributes.MaxObjects = 200001
jcs.default.cacheattributes.MemoryCacheName = org.apache.commons.jcs.engine.memory.lru.LRUMemoryCache
jcs.default.cacheattributes.MaxMemoryIdleTimeSeconds = 3600
jcs.default.elementattributes = org.apache.commons.jcs.engine.ElementAttributes
jcs.default.elementattributes.IsEternal = false
jcs.default.elementattributes.MaxLife = 700
jcs.default.elementattributes.IdleTime = 1800
jcs.default.elementattributes.IsRemote = true
thread_pool.default.maximumPoolSize = 150
thread_pool.default.minimumPoolSize = 4
----
`java.util.Properties` or from a classpath resource
Lot of samples http://svn.apache.org/repos/asf/commons/proper/jcs/trunk/commons-jcs-core/src/test/conf/[here]
== Cache types
- `IMemoryCache`: node storage (LRU, FIFO, MRU)
- CACHE_HUB: facade (just behind the API)
- DISK_CACHE: overflow storage (block, indexed, DB).
- LATERAL_CACHE: intended to broadcast write actions to other local caches ( often`SocketServer`).
- REMOTE_CACHE: client or server but in a remote cache architecture (RMI/HTTP)
== Listeners?
[fragment]#`I*CacheListener`: for plugins, bound to an event queue (sync/async).#
[fragment]#`ICacheEventLogger`: you get `ICacheEvent`...from auxilaries.#
[fragment medium]#So no events?#
[fragment big]#Auxilary ;)#
== Serialization?
- `IElementSerializer`
- JVM serialization
- JVM + ZLIB
- Custom
== JCS And Remoting
- HTTP
- UDP (+ discovery)
- TCP
- RMI (remote client/server)
== JCS And Monitoring
Mainly based on JMX
- Regions management (JCSAdmin MBean)
- JCache MBeans (statistics, configuration, `clear()`)
image::img/jmx.png[JCS]
- Admin servlet (1-1 MBean)
== JCS sample
[source,numbered,java]
----
final CacheAccess[String, String] cache = JCS.getInstance("mycache");
cache.put("jug", "lorraine");
assertEquals("lorraine", cacheAccess.get("jug"));
----
== JCS a word before going futher
____
JCS works well as local cache but
once auxilaries configured it is a simple and
efficient distributed cache as well.
____
== And JCache?
[medium]#First implementation done!#
== JCache in two words
- Standardization (after years) of caching API
- "Map" like API
- Events
- Light computing on data
- External system integration (DB, ...)
- CDI
- Expiry
- ...
== JCache API
[fragment]#Caching -> CacheProvider -> CacheManager -> Cache#
[fragment big]#or#
[fragment]#Caching -> Cache#
== JCache Advanced features
- Bulk loading (+`CompletionListener`)
- Entry processing (`EntryProcessor`)
- Listeners (`CacheEntry*Listener`)
== Main Implementations
- RI
- EhCache
- Hazelcast
- Infinispan
- Coherence
- JCS ;)
- ~ Spring
== JCache basic sample
[source,numbered,java]
----
try (CachingProvider provider = Caching.getCachingProvider()) {
try (CacheManager manager = provider.getCacheManager()) {
try (Cache[String, String] cache = manager.createCache(
"getting-started", new MutableConfiguration[String, String]())) {
cache.putIfAbsent("jug", "lorraine");
assertEquals("lorraine", cache.get("jug"));
}
}
}
----
== JCache processing
[source,numbered,java]
----
cache.putIfAbsent("jug", "lorraine");
int l = cache.invoke("jug", new EntryProcessor[String, String, Integer]() {
@Override
public Integer process(
final MutableEntry[String, String] entry,
final Object... arguments) throws EntryProcessorException {
if (entry.exists()) {
entry.setValue(arguments[0].toString());
}
return entry.getValue().length();
}
}, "best jug ever");
assertEquals("best jug ever".length(), l);
assertEquals("best jug ever", cache.get("jug"));
----
== JCache events
[source,numbered,java]
----
public interface CacheEntryListenerConfiguration[K, V] extends Serializable {
Factory[CacheEntryListener[? super K, ? super V]] getCacheEntryListenerFactory();
Factory[CacheEntryEventFilter[? super K, ? super V]] getCacheEntryEventFilterFactory();
boolean isOldValueRequired();
boolean isSynchronous();
}
----
`javax.cache.configuration.FactoryBuilder`
`SingletonFactory`
`ClassFactory`
See demo for a real sample
== JCache + CDI
[source,numbered,java]
----
@CacheDefaults(cacheName = "accounts")
public class AccountManager {
@CacheResult
public Account createAccount(@CacheKey String name,
String importantData) {
// ...
}
@CacheRemove
public void deleteAccount(String name) {
// ...
}
@CacheRemoveAll
public void bankruptcy() {
// ...
}
@CachePut
public void addAccount(@CacheKey String id, @CacheValue Account name) {
// ...
}
}
----
== JCache and JCS Extensions
- OpenJPA L2 Cache (JCache based)
- JCache extras (CDI, Web filter, writers/loaders - async, composite)
== JCache OpenJPA extension
- 100% using JCache API (portable)
[source,java,numbered]
----
app
----
== JCache CDI extension
- 100% using JCache API (portable)
[source,java,numbered]
----
@Inject
private CachingProvider provider;
@Inject
private CacheManager mgr;
----
== JCache Elsewhere?
CXF JAXRS HTTP caching!
[source,java,numbered]
----
ClientBuilder.newBuilder()
.register(CacheControlFeature.class)
.build()
.target("...")
.get();
----