The Transient Store allows to store temporary blobs and associated parameters on a Nuxeo instance but outside the repository, thus the "transient" aspect.
It is typically used by:
- The new Batch Upload API to store a batch of uploaded blobs until they are attached to a document.
- The ConversionService to store the BlobHolder resulting from an Asynchronous Conversion Work.
The new Transient Store API allows this simply:
void putBlobs(String key, List blobs);
List getBlobs(String key);
void putParameters(String key, Map parameters);
Map getParameters(String key);
void putParameter(String key, String parameter, Serializable value);
Serializable getParameter(String key, String parameter);
Configuration
You can configure several Transient Stores with the following extension point:
<extension target="org.nuxeo.ecm.core.transientstore.TransientStorageComponent"
point="store">
<store name="myTransientStore" class="my.transientstore.implementation">
<targetMaxSizeMB>-1</targetMaxSizeMB>
<absoluteMaxSizeMB>-1</absoluteMaxSizeMB>
<firstLevelTTL>240</firstLevelTTL>
<secondLevelTTL>10</secondLevelTTL>
</store>
</extension>
The store
tag supports two attributes:
name
: Used to identify the store.class
: References an implementation of theTransientStore
interface (default isSimpleTransientStore
).
Nested configuration elements are:
targetMaxSizeMB
: The target size that ideally should never be exceeded.absoluteMaxSizeMB
: The size that must never be exceeded.firstLevelTTL
: TTL in minutes of the first level cache.secondLevelTTL
: TTL in minutes of the second level cache.
Have a look at the default Transient Store configuration defined in a template:
<?xml version="1.0"?>
<component name="org.nuxeo.ecm.core.transient.store.config">
<#if "${nuxeo.redis.enabled}" == "true">
<#assign className = "org.nuxeo.ecm.core.redis.contribs.RedisTransientStore" />
<#else>
<#assign className = "org.nuxeo.ecm.core.transientstore.SimpleTransientStore" />
</#if>
<extension target="org.nuxeo.ecm.core.transientstore.TransientStorageComponent"
point="store">
<store name="default" class="${className}">
<targetMaxSizeMB>-1</targetMaxSizeMB>
<absoluteMaxSizeMB>-1</absoluteMaxSizeMB>
<firstLevelTTL>240</firstLevelTTL>
<secondLevelTTL>10</secondLevelTTL>
<minimalRetention>10</minimalRetention>
</store>
</extension>
</component>
The class is dynamically defined depending on if Redis is enabled or not. If you need to define a custom Transient Store we strongly recommend you use such a template with this dynamic class definition mechanism so that:
- In dev mode where usually Redis is not enabled you rely on the in-memory cache implementation.
- In cluster mode where Redis needs to be enabled the data stored in the Transient Store is distributed.
To get a given Transient Store just call TransientStoreService#getStore(String name)
.
If the store doesn't exist the default one is retrieved (if for any reason the default store is not registered it is registered using the SimpleTransientStore
implementation).
Implementation
As seen above there are two implementations. They both handle file storage the same way but store the data differently.
File Storage
The caching directory used by any Transient Store is located in $DATA_DIR/transientstores/<transientstore_name>
.
Typically for the default Transient Store on an instance with the Nuxeo data directory not externalized: nxserver/data/transientstores/default
.
In a cluster environment the caching directory must be shared by all the Nuxeo instances, see the related documentation.
Data Storage
The SimpleTransientStore
relies on Nuxeo's in-memory cache implementation using Google's Guava cache.
It is not distributed and not persistent.
The RedisTransientStore
relies on Redis.
It is distributed and persistent.
In a cluster environment Nuxeo must be configured to use a Redis server and any Transient Store accessed by multiple Nuxeo instances must use the RedisTransientStore
implementation.
See NXP-18051 for details about the RedisTransientStore
cluster aware implementation.
Examples
BatchManager
It relies on the BatchManagerCache
Transient Store which in fact is not registered so it falls back on the default store, this is to allow overriding the configuration if needed.
See the "Batch Upload Example" section of NXP-18050 for details.
TransientStoreWork
A Work allowing to store a result in a Transient Store.
It relies on the transientStoreWorkCache
Transient Store, also not registered with a fall back on the default store.
For example, the Asynchronous Conversions rely on such instances of TransientStoreWork
via the ConversionWork
class.
Time To Live and Garbage Collector
Entries have a Time To Live (TTL) defined in the store configuration.
By default the TTL is set to firstLevelTTL
, it can be set to secondLevelTTL
by calling TransientStore#release(String key)
.
Garbage collection:
- Is scheduled every 15 minutes to wipe the files associated to entries that don't exist anymore.
- Can be triggered manually on a given store with
TransientStore#doGC
or all stores withTransientStoreService#doGC
.