Ehcache calling loadAll cacheloaderwriter with single item iterable - ehcache

I am using Ehcache 3.1.1 on heap store.
cache = cacheManager.createCache(name,
CacheConfigurationBuilder.newCacheConfigurationBuilder(key, value, ResourcePoolsBuilder.heap(entries))
.withLoaderWriter(loader)
.build()
);
I have a CacheLoaderWriter which supports loadAll.
When making calls to getAll on the cache, misses route through to the loader, but call loadAll multiple times with single item iterators.
I believe this may be an issue in OnHeapStore bulkComputeIfAbsent
Please advise if I am missing a configuration to enable batching via loadAll.
I was unable to find this reported as a bug.
EDIT: I don't feel like I explained it well originally. So getAll is called with a key set size of 2, loadAll is called twice in that situation with the keyset being size of 1 each time.

You did nothing wrong in your configuration - please open an issue against Ehcache3

Related

Spring Boot Caching auto refresh using #PostConstruct

I currently have a Spring Boot based application where there is no active cache. Our application is heavily dependent on key-value configurations which we maintain in an Oracle DB. Currently, without cache, each time I want to get any value from that table, it is a database call. This is, expectedly causing a lot of overhead due to high number of transactions to the DB. Hence, the need for cache arrived.
On searching for caching solutions for SpringBoot, I mostly found links where we are caching object while any CRUD operation is performed via the application code itself, using annotations like #Cacheable, #CachePut, #CacheEvict, etc. but this is not applicable for me. I have a master data of key-value pairs in the DB, any change needs approvals and hence the access is not directly provided to the user, it is made once approved directly in the DB.
I want to have these said key-values to be loaded at startup time and kept in the memory, so I tried to implement the same using #PostConstruct and ConcurrentHashMap class, something like this:
public ConcurrentHashMap<String, String> cacheMap = new ConcurrentHashMap<>();
#PostConstruct
public void initialiseCacheMap() {
List<MyEntity> list = myRepository.findAll();
for(int i = 0; i < list.size(); i++) {
cacheMap.put(list.get(i).getKey(), list.get(i).getValue());
}
}
In my service class, whenever I want to get something, I am first checking if the data is available in the map, if not I am checking the DB.
My purpose is getting fulfilled and I am able to drastically improve the performance of the application. A certain set of transactions were earlier taking 6.28 seconds to complete, which are now completed in mere 562 milliseconds! however, there is just one problem which I am not able to figure out:
#PostConstruct is called once by Spring, on startup, post dependency injection. Which means, I have no means to re-trigger the cache build without restart or application downtime, this is not acceptable unfortunately. Further, as of now, I do not have the liberty to use any existing caching frameworks or libraries like ehcache or Redis.
How can I achieve periodic refreshing of this cache (let's say every 30 minutes?) with only plain old Java/Spring classes/libraries?
Thanks in advance for any ideas!
You can do this several ways, but how you can also achieve this is by doing something in the direction of:
private const val everyThrityMinute = "0 0/30 * * * ?"
#Component
class TheAmazingPreloader {
#Scheduled(cron = everyThrityMinute)
#EventListener(ApplicationReadyEvent::class)
fun refreshCachedEntries() {
// the preloading happens here
}
}
Then you have the preloading bits when the application has started, and also the refreshing mechanism in place that triggers, say, every 30 minutes.
You will require to add the annotation on some #Configuration-class or the #SpringBootApplication-class:
#EnableScheduling

Kotlin + Spring Boot - Add TTL to your map

So I have an empty map referenced like:
private var labelsForGroupId: Map<GroupId, Label> = emptyMap()
to lower the amount of calls through network api. After first call I cache the response to the map.
However, I would love to add TTL to that map, (for example, every hour it should be empty again). I am quite new to Kotlin, so wondering what would be the best approach here with some examples?
Instead of using a Map, you could use Guava Cache. It works like a Map (key-value) and have expiration policies.
Expiration by time example:
CacheBuilder.newBuilder()
.expireAfterAccess(200, TimeUnit.MILLISECONDS)
.build(loader);
If you are not interested in caches at all, then you could try to setup a Coroutine with a ScheduledExecutorService as Dispatcher. I never did this before but is a way out. Take a look at the Executors documentation - Coroutine context and dispatchers
If the given [ExecutorService] is an instance of
[ScheduledExecutorService], then all time-related * coroutine
operations such as [delay], [withTimeout] and time-based [Flow]
operators will be scheduled * on this executor using
[schedule][ScheduledExecutorService.schedule] method. If the
corresponding * coroutine is cancelled, [ScheduledFuture.cancel] will
be invoked on the corresponding future.

Make Ehcache return expired data if LoaderWriter fails

Is it possible to set up Ehcache in such a way that cache will return "expired" data if the underlying CacheLoaderWriter fails (throws an Exception)?
Accordingly to my tests, if a given cache entry is expired, and CacheLoaderWriter fails to load data, cache returns null.
However, on my case, it would be better to return the expired cached data than nothing. What I am doing as a work around is to store the latest successfully loaded data in the CacheLoaderWriter, so if a new execution of the load fails, I return this copy. Anyway, think that would be more "memory efficient" to, somehow, return the data that it's already in the cache, instead of keeping another copy in the CacheLoaderWriter.
I am using ehcache 3.4.0
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.withCache("myCacheName",
CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class, ResourcePoolsBuilder.heap(100))
.withExpiry(Expirations.timeToLiveExpiration(Duration.of(4, TimeUnit.HOURS)))
.withLoaderWriter(new TestCacheLoaderWriter()))
.build();
It is not possible. However, unless you are using a copier, it isn't a copy you are keeping in your loader-writer. It's only another reference to the object in cache.
Your request could be filed as an enhancement in the Ehcache issue tracker.
The alternative would be to never expire the data but replacing it from outside when needed.

Project reactor processors v3.X

We are trying to migrate from 2.X to 3.X.
https://github.com/reactor/reactor-core/issues/375
We have used the EventBus as event manager in our application(Low latency FX system) and it works very well for us.
After the change we decided to take every module and create his own processor to handle event.
1. Does this use seems to be correct from your point of view? Because lack of document at the current stage and after reviewing everything we could we don't really know what to do here
2. We have tried to use Flux in order to perform action every X interval
For example: Market is arriving 1000 for 1 second but we want to process an update only 4 time in a second. After upgrading we are using:
Processor with buffer and sending to another method.
In this method we have Flux that get list and try to work in parallel in order to complete his task.
We had 2 major problems:
1. Sometimes we received Null event which we cannot find that our system is sending to i suppose maybe we are miss using the processor
//Definition of processor
ReplayProcessor<Event> classAEventProcessor = ReplayProcessor.create();
//Event handler subscribing
public void onMyEventX(Consumer<Event> consumer) {
Flux<Event> handler = classAEventProcessor .filter(event -> event.getType().equals(EVENT_X));
handler.subscribe(consumer);
}
in the example above the event in the handler sometimes get null.. Once he does the stream stop working until we are restating server(Because only on restart we are doing creating processor)
2.We have tried to us parallel but sometimes some of the message were disappeared so maybe we are misusing the framework
//On constructor
tickProcessor.buffer(1024, Duration.of(250, ChronoUnit.MILLIS)).subscribe(markets ->
handleMarkets(markets));
//Handler
Flux.fromIterable(getListToProcess())
.parallel()
.runOn(Schedulers.parallel())
.doOnNext(entryMap -> {
DoBlockingWork(entryMap);
})
.sequential()
.subscribe();
The intention of this is that the processor will wakeup every 250ms and invoke the handler. The handler will work work with Flux parallel in order to make better and faster processing.
*In case that DoBlockingWork takes more than 250ms i couldn't understand what will be the behavior
UPDATE:
The EventBus was wrapped by us and every event subscribed throw the wrapped event manager.
Now we have tried to create event processor for every module but it works very slow. We have used TopicProcessor with ThreadExecutor and still very slow.. EventBus did the same work in high speed
Anyone has any idea? BTW when i tried to use DirectProcessor it seems to work much better that the TopicProcessor
Reactor 3 is built around the concept that you should avoid blocking as much as you can, so in your second snippet DoBlockingWork doesn't look good.
How are the events generated? Do you maybe have an listener-based asynchronous API to get them? If so, you could try using Flux.create.
For your use case of "we have 1000 events in 1 second, but only want to process 4", I'd chain a sample operator. For instance, sample(Duration.ofMillis(250)) will divide each second into 4 windows, from which it will only emit the last element.
The reference guide is being written, as well as a page where you can find links to external articles and learning material.There's a preview of the WIP reference guide here and the learning resources page here.

Symfony2 AppCache performance boost

We're trying to figure out what effect enabling AppCache in the frontend controller has on caching without calling any cache directives on the response object.
I had presumed that simply adding the following line and setting default_ttl to 1:
$kernel = new AppCache($kernel);
would not change the behaviour of the application without calling a cache directive on the response. But as soon as we add this line (and cache:clear) our server is able to handle far more requests per second, which suggests that there is some caching going on.
Turning on debug and setting default_ttl to an hour all we see in the http headers is
X-Symfony-Cache: GET /: miss
Does this mean that there is no reverse proxy caching going on? If so what explains the performance increase?
Any clarification on what happens in this situation would be awesome.
This line
$kernel = new AppCache($kernel);
enables the Symfony2 Reverse Proxy. For further explanation follow this link: http://symfony.com/doc/current/book/http_cache.html#symfony2-reverse-proxy. The performance increase should be clear now.
The header means that the "Symfony-Cache" got a "GET" request and found no cached data ("miss"). If you call the same page multiple times in a row the header should change to something like:
X-Symfony-Cache: GET /: HIT 42

Resources