All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sirius.kernel.cache.CacheManager Maven / Gradle / Ivy

Go to download

Provides common core classes and the microkernel powering all Sirius applications

There is a newer version: 12.9.1
Show newest version
/*
 * Made with all the love in the world
 * by scireum in Remshalden, Germany
 *
 * Copyright by scireum GmbH
 * http://www.scireum.de - [email protected]
 */

package sirius.kernel.cache;

import sirius.kernel.Stoppable;
import sirius.kernel.di.std.Part;
import sirius.kernel.di.std.Register;
import sirius.kernel.health.Exceptions;
import sirius.kernel.health.Log;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

/**
 * Provides access to all managed caches
 * 

* Is responsible for creating new caches using {@link #createLocalCache(String)} or {@link #createCoherentCache(String)}. * Also, this class keeps track of all known caches. *

* Additionally instances of {@link InlineCache} can be created, which can be used to compute a single value, * which is then cached for a given amount of time. */ public class CacheManager { /** * Logged used by the caching system */ protected static final Log LOG = Log.get("cache"); /** * Lists all known caches. */ private static Map> caches = new ConcurrentHashMap<>(); private static final Duration INLINE_CACHE_DEFAULT_TTL = Duration.ofSeconds(10); @Part private static CacheCoherence cacheCoherence; /** * This class has only static members and is not intended to be instantiated */ private CacheManager() { } /** * Returns a list of all known caches * * @return a list of all caches created so far */ public static List> getCaches() { return new ArrayList<>(caches.values()); } /** * Creates a cache with the given name which is only managed locally. *

* The name is used to load the settings from the system configuration, using the extension cache.[name]. * If a value is absent in the cache, the given valueComputer is used to generate the requested value. If * a value is fetched from the cache, it is verified by the given verifier in certain intervals before it * is returned to the user. *

* The system config can provide the following values: *

    *
  • maxSize: max number of entries in the cache
  • *
  • ttl: a duration specifying the max lifetime of a cached entry.
  • *
  • verification: a duration specifying in which interval a verification of a value will * take place (if possible)
  • *
*

* To create a cache which is maintained across a cluster of nodes, use * {@link #createCoherentCache(String, ValueComputer, ValueVerifier)}. * * @param name the name of the cache, used to load the appropriate extension from the config * @param valueComputer used to compute a value, if no valid value was found in the cache for the given key. Can * be null if there is no appropriate way to compute such a value. In this case, the * cache will simply return null. * @param verifier used to verify a value before it is returned to the user. Note that the * value is not verified each time, but in given intervals. If the verifier is null, * no verification will take place. * @param the key field used to identify cache entries * @param the value type used by the cache * @return a newly created cache according to the given parameters and the settings in the system config */ public static Cache createLocalCache(String name, ValueComputer valueComputer, ValueVerifier verifier) { ManagedCache result = new ManagedCache<>(name, valueComputer, verifier); verifyUniquenessOfName(name); caches.put(name, result); return result; } private static void verifyUniquenessOfName(String name) { if (caches.containsKey(name)) { throw Exceptions.handle() .to(LOG) .withSystemErrorMessage("A cache named '%s' has already been created!", name) .handle(); } } /** * Creates a cache with the given name, for which removals are roamed in the cluster to prevent stale values. *

* All other settings are exactly the same as for local caches. Also, if no {@link CacheCoherence} is present, * this will behave like a local cache. * * @param name the name of the cache, used to load the appropriate extension from the config * @param valueComputer used to compute a value, if no valid value was found in the cache for the given key. Can * be null if there is no appropriate way to compute such a value. In this case, the * cache will simply return null. * @param verifier used to verify a value before it is returned to the user. Note that the * value is not verified each time, but in given intervals. If the verifier is null, * no verification will take place. * @param the value type used by the cache * @return a newly created cache according to the given parameters and the settings in the system config * @see #createLocalCache(String, ValueComputer, ValueVerifier) */ public static Cache createCoherentCache(String name, ValueComputer valueComputer, ValueVerifier verifier) { CoherentCache result = new CoherentCache<>(name, valueComputer, verifier); verifyUniquenessOfName(name); caches.put(name, result); return result; } /** * Creates a locally managed cache with the given name. *

* This is just a shortcut for {@link #createLocalCache(String, ValueComputer, ValueVerifier)} with neither a * ValueComputer nor a ValueVerifier supplied. * * @param the key field used to identify cache entries * @param the value type used by the cache * @param name the name of the cache (used to fetch settings from the system config * @return the newly created cache * @see #createLocalCache(String, ValueComputer, ValueVerifier) */ public static Cache createLocalCache(String name) { return createLocalCache(name, null, null); } /** * Creates a coherent cache with the given name. *

* This is just a shortcut for {@link #createCoherentCache(String, ValueComputer, ValueVerifier)} with neither a * ValueComputer nor a ValueVerifier supplied. * * @param the value type used by the cache * @param name the name of the cache (used to fetch settings from the system config * @return the newly created cache * @see #createLocalCache(String, ValueComputer, ValueVerifier) */ public static Cache createCoherentCache(String name) { return createCoherentCache(name, null, null); } /** * Creates a new {@link InlineCache} with the given TTL and computer. *

* An inline cache can be used to compute a single value, which is then cached for a certain amount of time. * * @param ttl specifies the duration which the computed value will be cached * @param computer the provider which is used to re-compute the value once it expired * @param the type of values being cached * @return an inline cache which keeps a computed value for the given amount of time and then uses the provided * computer to re-compute the value */ public static InlineCache createInlineCache(Duration ttl, Supplier computer) { return new InlineCache<>(computer, ttl.toMillis()); } /** * Boilerplate method for {@link #createInlineCache(Duration, Supplier)} * which keeps the computed value for up to 10 seconds. * * @param computer the provider which is used to re-compute the value once it expired * @param the type of values being cached * @return an inline cache which keeps a computed value for ten seconds and then uses the provided * computer to re-compute the value */ public static InlineCache createTenSecondsInlineCache(Supplier computer) { return createInlineCache(INLINE_CACHE_DEFAULT_TTL, computer); } /** * Used by {@link CoherentCache} to signal that this cache is to be cleared on all nodes. * * @param cache the cache to clear */ protected static void clearCoherentCache(CoherentCache cache) { if (cacheCoherence != null) { cacheCoherence.clear(cache); } else { cache.clearLocal(); } } /** * Clears the coherent cache locally. * * @param cacheName the cache to clear */ public static void clearCoherentCacheLocally(String cacheName) { ManagedCache cache = caches.get(cacheName); if (cache instanceof CoherentCache) { ((CoherentCache) cache).clearLocal(); } } /** * Used by {@link CoherentCache} to signal that the given key should be removed from this cache on all nodes. * * @param cache the cache to remove the value from * @param key the key to remove */ protected static void removeCoherentCacheKey(CoherentCache cache, String key) { if (cacheCoherence != null) { cacheCoherence.removeKey(cache, key); } else { cache.removeLocal(key); } } /** * Removes the given key from the given cache locally. * * @param cacheName the name of the cache to remove the value from * @param key the key to remove */ public static void removeCoherentCacheKeyLocally(String cacheName, String key) { ManagedCache cache = caches.get(cacheName); if (cache instanceof CoherentCache) { ((CoherentCache) cache).removeLocal(key); } } /** * Clears the caches when Sirius is shutting down */ @Register public static class CacheManagerLifecycle implements Stoppable { @Override public void stopped() { caches.values().forEach(ManagedCache::clear); caches.clear(); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy