Cache Functions
Overview
Martini's Cache Functions let you store, retrieve, invalidate, and manage named cache entries directly inside your workflows and services. By keeping frequently accessed data in a fast in-memory store, you avoid repeating expensive database queries or external API calls on every workflow or service execution.
Cache Functions work with named caches you declare in your Martini package configuration, giving you full control over what gets cached, for how long, and how it is invalidated. Beyond simple get/put/invalidate operations, Cache Functions also expose named-cache management operations — listing configured caches, inspecting keys and size, checking key existence, clearing an entire cache, and invalidating String keys that match a glob pattern — so you can build diagnostics, warm-up verification, and cache-management workflows without external tooling.
What You Will Learn
- How
cacheGet,cachePut, andcacheInvalidatework and when to use each - How
cachePutapplies a per-entry expiry usingexpireAfterWriteandexpireAfterAccessoptions - How the
packageNameparameter identifies which package owns the cache you're targeting - How to discover configured cache names with
cacheList, and inspect a cache'scacheGetKeysandcacheGetSize - How to check whether a key exists with
cacheContainsKey, including how it differs from a storednullvalue - How to clear an entire cache with
cacheEvictAlland invalidate a subset of String keys withcacheInvalidatePattern - The input parameters each function requires
- How to configure the named cache provider that backs these functions
- How to troubleshoot common cache function issues
When To Use This
Use Cache Functions when:
- A workflow or service repeatedly fetches the same data from a database or external API within a short time window
- You want to reduce response latency by serving repeated requests from memory instead of a live data source
- You need to share computed results across multiple workflow or service calls within the same Martini package
- You want to explicitly expire or remove a cached value when the underlying data changes
- You need to diagnose cache behavior — confirm which caches are configured, inspect their current keys or size, or verify that a warm-up step populated an expected key
- You need to clear a named cache entirely, or invalidate only the entries whose String keys match a pattern
Prerequisites
- Martini Designer installed and running
- A Martini Package with at least one service or workflow
- A named cache declared in your Martini package's
caches.conffile — see Martini Package Cache Configuration for setup instructions
Cache Functions Reference
Cache Functions, grouped under the Cache folder in the Functions view, are the core building blocks for interacting with named caches at runtime. Most functions target a specific named cache and act on a single entry identified by its key; a smaller set of management functions operate on the cache as a whole.
Cache Functions Key Terms
The following terms describe the parameters and concepts common to all Cache Functions.
| Term | Definition |
|---|---|
| packageName | The name of the Martini package that owns the named cache. Pass null to target a cache declared in the current package. |
| cacheName | The identifier of the named cache to use. Must match a cache name declared in the owning package's caches.conf file exactly. |
| key | A value that identifies a specific entry within the cache. Used to store, retrieve, check, or remove an entry. |
| value | The data you want to store in the cache. Accepted as any object; typically a string, number, map, or serializable model object. |
| entry | A single item stored in the cache, consisting of a key and its associated value. |
Understanding the packageName Parameter
Every Cache Function accepts a packageName input parameter that determines which Martini package's
caches.conf configuration owns the named cache being targeted.
| Scenario | What to Set packageName To |
|---|---|
| The cache is declared in the same package you are working in | null — targets the current package |
| The cache is declared in a different package in your workspace | The name of the package that declares the cache in its caches.conf |
cacheGet(null, "productCache", "product-42", null)— targetsproductCachein the current packagecacheGet("shared-caching", "productCache", "product-42", null)— targetsproductCachedeclared in theshared-cachingpackage
Available Cache Functions
The table below lists the available Cache Functions, their inputs, and their purpose.
| Function | What It Does |
|---|---|
cacheGet(packageName, cacheName, key[, defaultValue]) |
Returns the value stored under key; if no entry exists, returns defaultValue (defaults to null when omitted). |
cachePut(packageName, cacheName, key, value, expiryOptions) |
Stores value under key, applying an optional per-entry expiryOptions override. Overwrites any existing entry. |
cacheInvalidate(packageName, cacheName, key) |
Removes the entry for key from the cache immediately. |
cacheList(packageName) |
Returns the names of the caches configured for the specified package. |
cacheGetKeys(packageName, cacheName) |
Returns the keys currently present in the named cache. |
cacheGetSize(packageName, cacheName) |
Returns the current number of mappings in the named cache. |
cacheContainsKey(packageName, cacheName, key) |
Returns whether key currently has an entry in the named cache. |
cacheEvictAll(packageName, cacheName) |
Removes every entry from the named cache. |
cacheInvalidatePattern(packageName, cacheName, keyPattern) |
Removes entries whose String key matches a glob keyPattern and returns the number removed. |
Compatibility Overloads
Some Cache Functions retain overloads without a packageName parameter for compatibility with
existing services and workflows, always targeting the current package.
The cachePut(cacheName, key, value) overload without expiry options is hidden from the generated
function surface; use cachePut(packageName, cacheName, key, value, expiryOptions) instead — see
Setting Per-Entry Expiry with cachePut.
How Cache Functions Work
Each Cache Function operates on the named cache you specify at the time of the call. Martini resolves
the cache name to the provider configured in caches.conf (Guava, Ehcache, or Redis), so your
function calls remain the same regardless of the underlying storage backend.
Typical read-through pattern:
- Call
cacheContainsKey(packageName, cacheName, key)to check whether the key is present. - If the key exists, call
cacheGet(packageName, cacheName, key, null)and use the returned value (which may benull). - If the key does not exist, fetch the data from the source (database, API, etc.).
- Call
cachePutto store the fresh value under the samekeyfor future requests. - When the source data changes, call
cacheContainsKeybeforecacheInvalidateto confirm the key was cached, then remove the stale entry so the next request fetches updated data.
Entry lifecycle:
- Entries expire automatically according to the
expireAfterWriteorexpireAfterAccesspolicy defined incaches.conf, unless overridden per entry — see Setting Per-Entry Expiry withcachePut. cacheInvalidateandcacheInvalidatePatternremove entries immediately, before their expiry elapses.cacheEvictAllclears every entry in the named cache immediately.cachePuton an existing key replaces the value and resets the entry's expiry timer.
Setting Per-Entry Expiry with cachePut
cachePut(packageName, cacheName, key, value, expiryOptions) stores value under key and lets you
override the cache's configured expiry policy for that single entry using an expiryOptions model.
| Property | Required | Description |
|---|---|---|
expireAfterWrite |
No | Duration, in seconds, before this entry is evicted after it is created or last replaced. |
expireAfterAccess |
No | Duration, in seconds, before this entry is evicted after it is created, last replaced, or last accessed. |
If expiryOptions is null, or neither property is set, the entry falls back to the expireAfterWrite /
expireAfterAccess policy declared for the cache in caches.conf. Setting expireAfterWrite and/or
expireAfterAccess on the call requests an override for that entry only; other entries in the same
cache are unaffected.
Provider-Dependent Support
Support for per-entry expiry configuration depends on the cache provider. Some providers may ignore one or both expiry options, may not support setting expiry on individual entries at all, or may interpret zero or negative expiry values differently. Verify behavior against your configured provider before relying on per-entry overrides.
For providers that support per-entry expiry overrides, cachePut(null, "productCache", "product-42", productObject, [expireAfterWrite: 30]) stores productObject and expires it 30 seconds after it is written for that entry only.
Discovering and Inspecting Caches
Use these functions to discover which named caches are configured for a package, and to inspect a specific cache's contents before reading, writing, or invalidating entries.
| Function | Return Value | Description |
|---|---|---|
cacheList(packageName) |
List<String> — exposed as cacheNames |
Lists every cache configured for packageName in its caches.conf file. |
cacheGetKeys(packageName, cacheName) |
List<Object> — exposed as keys |
Lists the keys currently present in the named cache. |
cacheGetSize(packageName, cacheName) |
long — exposed as size |
Returns the current number of mappings in the named cache. |
cacheContainsKey(packageName, cacheName, key) |
boolean |
Returns whether key currently has an entry, distinguishing it from a null value stored under that key. |
cacheList Excludes Package Dependencies
cacheList returns only the caches declared in the specified package's own caches.conf file.
It does not include caches declared by that package's dependencies. If the package declares no
caches, cacheList returns an empty list.
cacheName and key are required for cacheContainsKey. Because it reports whether an entry exists
rather than what its value is, cacheContainsKey lets you tell apart a key that was never cached from a
key whose stored value is null — a distinction cacheGet alone cannot make, since it returns null
for both cases.
Diagnostic flow — verify key presence before reading or invalidating:
flowchart TD
A["List configured caches: cacheList(null)"] --> B["Inspect the target cache: cacheGetKeys(null, cacheName) / cacheGetSize(null, cacheName)"]
B --> C{"cacheContainsKey(null, cacheName, key)?"}
C -->|Yes| D{"Read or invalidate?"}
D -->|Read| E["Read the value: cacheGet(null, cacheName, key, null)"]
D -->|Invalidate| F["Remove the key: cacheInvalidate(null, cacheName, key)"]
C -->|No| G["Key was never cached — skip invalidation and handle separately from a cached null value"]
Clearing and Invalidating Cache Entries
Use these functions when you need to remove entries in bulk, rather than one key at a time with
cacheInvalidate.
| Function | Return Value | Description |
|---|---|---|
cacheEvictAll(packageName, cacheName) |
void |
Removes every entry from the named cache. |
cacheInvalidatePattern(packageName, cacheName, keyPattern) |
long — exposed as invalidatedCount |
Removes only the entries whose String key matches keyPattern, and returns the number of entries removed. |
cacheEvictAll clears the entire cache unconditionally. cacheInvalidatePattern instead removes a
subset of entries selected by matching their key against keyPattern using glob syntax:
*matches any sequence of characters (including none)?matches exactly one character
String Keys Only
Pattern matching with cacheInvalidatePattern is only reliable for entries whose keys are String
values. Behavior is undefined for caches that use non-String keys.
Clearing one named cache:
cacheEvictAll(null, "sessionCache") removes every entry from sessionCache in the current package.
Invalidating String keys with a glob pattern:
cacheInvalidatePattern(null, "productCache", "product-*") removes every entry whose key starts with product- (for example product-42, product-100) and returns the count of entries removed.
cacheEvictAll and cacheInvalidatePattern differ in scope: cacheEvictAll always empties the whole
cache, while cacheInvalidatePattern only removes the entries matching the pattern, leaving unrelated
entries untouched, and reports how many were removed via invalidatedCount.
Cache Functions Benefits and Use Cases
Cache Functions eliminate unnecessary repetition in your workflows and services, which directly improves throughput and reduces load on downstream systems.
Common scenarios include:
- Reference data caching — Store lookup tables (country codes, product categories) that change infrequently but are read on every request.
- API response caching — Cache the result of a slow or rate-limited third-party API call so only the first caller in a time window pays the latency cost and subsequent calls are served from cache without consuming your API quota.
- Session-scoped computation — Store the result of an expensive calculation and share it across multiple steps within the same execution context.
- Invalidation on write — Call
cacheInvalidateorcacheInvalidatePatternimmediately after updating a database record to ensure the next read fetches fresh data instead of a stale cached copy. - Cache maintenance and diagnostics — Use
cacheList,cacheGetKeys, andcacheGetSizeto confirm a package's caches are configured and populated as expected, without external tooling.
Troubleshooting Cache Function Issues
The following table covers the most common problems encountered when using Cache Functions.
| Problem | Detection | Cause | Fix | Affected Versions |
|---|---|---|---|---|
cacheGet always returns null |
No cached values retrieved; every call hits the source | cacheName in the function does not match the name declared in caches.conf |
Verify the cacheName parameter matches the cache block name in caches.conf exactly |
All |
cachePut has no effect |
Values stored but not retrievable on next call | The cache entry expires too quickly due to a short TTL in caches.conf or a short per-entry expiryOptions override |
Increase expireAfterWrite or expireAfterAccess in caches.conf, or in the expiryOptions passed to cachePut |
All |
cacheInvalidate throws a runtime error |
Service fails with a cache-related exception | The named cache does not exist or the Martini package has not been restarted | Confirm the caches.conf file is saved and restart the Martini package to reload config |
All |
| Cache not available after package restart | Functions fail with "cache not found" error | caches.conf is missing from the Configuration directory of the Martini package |
Create the caches.conf file and declare the required named cache — see Martini Package Cache Configuration |
All |
cacheList returns an empty list even though caches exist |
No cache names returned | The caches are declared in a dependency package, not in packageName itself, or caches.conf is missing from that package |
Pass the packageName of the package that directly declares the caches in its own caches.conf; cacheList never returns caches from dependencies |
All |
cacheInvalidatePattern removes unexpected entries or misses expected ones |
Wrong set of keys invalidated | The cache uses non-String keys, or the glob keyPattern does not account for */? semantics |
Use cacheInvalidatePattern only for caches with String keys, and verify the pattern against sample keys |
All |
Configuring the Cache Provider
Cache Functions rely on named caches that you declare at the Martini package level. The provider you choose (Guava, Ehcache, or Redis) determines the storage type, capacity limits, and whether the cache is local or distributed.
Setting Up a Named Cache for Cache Functions
To make a named cache available to your Cache Functions, define it in the caches.conf file inside
your Martini package's Configuration directory.
Minimal Guava example:
1 2 3 4 | |
Using this cache in a Workflow (current package, packageName = null):
cacheGet(null, "productCache", "product-42", null)— retrieves the entry with keyproduct-42cachePut(null, "productCache", "product-42", productObject, null)— storesproductObjectunderproduct-42using the cache's default expirycacheInvalidate(null, "productCache", "product-42")— removes the entry immediatelycacheList(null)— returns["productCache"]for this package
Expected result: The workflow reads from and writes to the productCache Guava cache, with entries
automatically evicted five minutes after they are written. Guava uses cache-wide expiry, so
per-entry expiryOptions overrides are not applied.
For full provider configuration options including Ehcache and Redis, see Martini Package Cache Configuration.
Helpful Resources
- Martini Package Cache Configuration - Declare and configure named caches (Guava, Ehcache, Redis) at the Martini package level
- Workflow Overview - Understand how Workflows are structured and how Cache Functions can be used within them
- Martini Package Overview - Understand Martini package structure,
including the
Configurationdirectory wherecaches.conflives - Community Q&A: Martini Community
Have a question? Post or search it here.