Datastore transactions are generally much more expensive than Memcache transactions and is a significant source of application contention in heavily used apps.

Before we get to the actual implementation, there are some interesting facts about GAE caching that you should know.

Values can expire from the Memcache at any time, and may be expired prior to the expiration deadline set for the value. The app engine platform would be managing the expiration and the advice is that we should be prepared to lose the value before the actual expiration that we have defined. Why?

That is because, although, Memcache is segmented by application which means that every app is guaranteed a fair share of Memcache space, however, the nature of the Memcache is that you are sharing it with a lot of other applications. If other apps are Memcache hungry then memory pressure will eventually push your inactive values out of the cache even before the expiration.

Memcache API respects the Namespace so it is easy to use it in the multi-tenant application like ours.

GAE provides support for JCache, a proposed interface standard for memory caches, as an interface to the App Engine Memcache. This interface is described by JSR 107. App Engine provides this interface using the net.sf.jsr107 interface package. One thing that you would have to keep in mind is that you need to include the appengine-jsr107cache-1.3.7.jar as a part of your war. If you are using a maven structure then the dependency would be

As you would notice, we create the expensive CacheFactory in a static block and get a reference to the Cache which we use throughout the application.

Once you have the Cache controller, there are 2 ways to write your caching strategy.

Invasive – this would mean that your services might be aware of the Caching service

Non- Invasive – the services are not aware that there exists a caching framework

In this post we would try to understand the former i.e. the invasive strategy.

I call it invasive because the application is well aware of the caching framework and it uses it directly. I also call it invasive because my services do more than what they are supposed to do and apart from their own logic, they also take care of caching which defies the SRP principle and allows cross cutting concerns to be rendered with the application logic.

But nevertheless it is simple, let us look at an example in which we pull the projects assigned to the user and we also know that these are not going to change in the GCacheFactory.EXPIRATION_DELTA=1800 that we have configured the cache with.

Set it in the cache, so that next time it can be fetched from the cache.

This is one standard way to make sure that your application is using the cache effectively and is not hitting the datastore for the same keys again and again. The best candidates for caching are the entities that you would otherwise pull again and again, user preferences, session data etc.

In the next post, we would try to look at the non-invasive way of caching.

Like this:

Vikas is the CEO and Co-Founder of Knoldus Inc. Knoldus does niche Reactive and Big Data product development on Scala, Spark, and Functional Java. Knoldus has a strong focus on software craftsmanship which ensures high-quality software development. It partners with the best in the industry like Lightbend (Scala Ecosystem), Databricks (Spark Ecosystem), Confluent (Kafka) and Datastax (Cassandra).
Vikas has been working in the cutting edge tech industry for 20+ years. He was an ardent fan of Java with multiple high load enterprise systems to boast of till he met Scala. His current passions include utilizing the power of Scala, Akka and Play to make Reactive and Big Data systems for niche startups and enterprises who would like to change the way software is developed.
To know more, send a mail to hello@knoldus.com or visit www.knoldus.com