0 votes
8.3k views
in Toolkits by

1 Answer

0 votes
by (30.6k points)

A custom caching toolkit = a Java-backed cache (in-JVM, optionally distributed) wrapped by toolkit services so that every process app reads reference data with one call and never hits the source repeatedly. Design and a compact implementation:

// Java (managed jar): simple TTL cache per key, thread safe, per JVM (each cluster member has its own copy - fine for reference data)
public class RefCache {
  private static final ConcurrentHashMap<String, Object[]> CACHE = new ConcurrentHashMap<>();   // key -> [expiresAtMillis, jsonValue]
  public static String get(String key) { Object[] e = CACHE.get(key); if (e == null || (long) e[0] < System.currentTimeMillis()) { CACHE.remove(key); return null; } return (String) e[1]; }
  public static void put(String key, String json, long ttlSeconds) { CACHE.put(key, new Object[] { System.currentTimeMillis() + ttlSeconds * 1000, json }); }
  public static void evict(String prefix) { CACHE.keySet().removeIf(k -> k.startsWith(prefix)); }
  public static String stats() { return CACHE.size() + " entries"; }
}
// toolkit service flow "Get cached" - inputs key, ttlSeconds, loaderServiceName; output value (String JSON)
var v = RefCache.get(tw.local.key);                                            // Java integration step or LiveConnect: Packages.com.example.RefCache.get(...)
if (v == null) {
  var inputs = new tw.object.Map(); inputs.put("key", tw.local.key);
  var result = tw.system.executeServiceByName(tw.local.loaderServiceName, inputs);   // the loader knows how to fetch (SQL, REST) and returns JSON
  v = result.get("value");
  RefCache.put(tw.local.key, v, tw.local.ttlSeconds || 600);
}
tw.local.value = v;
// callers: tw.local.countries = JSON.parse( GetCached("ref:countries", 3600, "Load countries").value )

Design points: keys with a namespace prefix so that evict("ref:") clears a domain after an admin change (expose an Evict service and a tiny admin dashboard); TTLs per key type; store JSON strings (immutable, serialisable) rather than business objects; on a cluster either accept per-member copies (reference data) or use a distributed cache (Redis via Jedis, Hazelcast, or the WebSphere DynaCache DistributedMap from JNDI on traditional) when consistency matters; never cache per-user or transactional data. Compare with the built-in service caching (question 2897): the OOB cache is keyed by service inputs and cleared only by redeploy - the custom toolkit gives you TTL, eviction, statistics and cross-app sharing. On CP4BA the same jar works; for cross-pod caching use Redis (an operator-managed one) rather than in-JVM maps.

References

Related questions

0 votes
1 answer 1.6k views
0 votes
2 answers 2.9k views
0 votes
1 answer 2.1k views
0 votes
1 answer 1.1k views
0 votes
1 answer 1.3k views
+1 vote
1 answer 1.8k views
0 votes
1 answer 2.5k views
0 votes
2 answers 1.8k views

723 questions

807 answers

98 comments

4.9k users

Join BPM Community Discord Channel

Welcome to BPM Tips Q&A, Community wiki/forum where you can ask questions and receive answers from other IBM BPM experts and members of the community. Users with 2000 points will automatically be promoted to expert level.
Created by Dosvak LLC
Our Youtube Channel
...