sjngm
sjngm

Reputation: 12871

Spring Cache For Pending Method Calls

Let's say I'm writing a Spring web-service that gets called by an external application. That application requests data that I need to load from an external resource. Furthermore, the design has it that it calls my service more than once with different parameters. In other words, the user sitting in front of the application presses one button, which generates a bunch of requests to my web-service in a very short time frame.

My web-service parses the parameters and comes up with necessary requests to the external resource. The logic has it that it may cause calling the external resource with the same parameters over and over again, which makes this the ideal candidate for caching.

Example:

  1. The user presses that one button in the application
  2. Application initiates ten requests to my web-service
  3. My web-service receives them in parallel
  4. After analysing the parameters of all requests, overall I'd need to call the external resources 15 times, but the parameters are mostly equal and only show that three calls would be enough to serve the 15 intended calls.

However, one call to the external resource may take some time.

As far as I understand how Spring does caching it writes the result of a @Cachable method into the cache. Apparently this means that before it treats another invocation of that method with the same parameters as cache hit, it must have a result of a previous invocation. This means that it doesn't provide support for pending method calls.

I need something like "Hey, I just saw a method invocation with the same parameters a second ago, but I'm still waiting for the result of that invocation. While I can't provide a result yet, I will hold that new invocation and reuse the result for it."

What are my options? Can I make Spring do that?

Upvotes: 2

Views: 219

Answers (1)

Stephane Nicoll
Stephane Nicoll

Reputation: 33121

You can't make Spring do that out-of-the-box for very good reasons. The bottom line is that locking and synchronizing is very hard using a specific cache implementation so trying to do that in an abstraction is a bit insane. You can find some rationale and some discussion here

There is a discussion of using ehcache's BlockingCache SPR-11540

Guava also has such feature but the cache needs to be accessed in a very specific way (using a callback) that the CacheInterceptor does not really fit. It's still our plan to try to make that work at some point.

Do not forget that caching must be transparent (i.e. putting it on and off only leads to a performance change). Trying to parse arguments and compute what call should be made to your web service has high chances to lead to side effects. Maybe you should cache things at a different place?

Upvotes: 1

Related Questions