[Scala 2.2.3] Can I store a Future[T] in Cache

1,308 views
Skip to first unread message

John Langley

unread,
Jul 3, 2014, 10:06:42 AM7/3/14
to play-fr...@googlegroups.com
I believe the answer is yes, but I'd love a confirmation. 

The motivation is that I want to cache the result from making a WebService (WS) call, but of course, I don't want to block while I'm waiting for the result. So it seems the obvious solution is to use a Future. 

Thoughts? Thanks in advance. 


Filippo De Luca

unread,
Jul 3, 2014, 10:18:10 AM7/3/14
to play-fr...@googlegroups.com
You can store the result of a future. You can store also the future, but it is not portable you cannot serialize a Future.


--
You received this message because you are subscribed to the Google Groups "play-framework" group.
To unsubscribe from this group and stop receiving emails from it, send an email to play-framewor...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Filippo De Luca
---------------------

Mariot Chauvin

unread,
Jul 3, 2014, 10:35:27 AM7/3/14
to play-fr...@googlegroups.com
If it's in memory caching, have a look to spray-cache 

Cheers,

Mariot


Visit theguardian.com. On your mobile and tablet, download the Guardian iPhone and Android apps theguardian.com/guardianapp and our tablet editions theguardian.com/editions.  Save up to 57% by subscribing to the Guardian and Observer - choose the papers you want and get full digital access.  Visit subscribe.theguardian.com

This e-mail and all attachments are confidential and may also be privileged. If you are not the named recipient, please notify the sender and delete the e-mail and all attachments immediately. Do not disclose the contents to another person. You may not use the information for any purpose, or store, or copy, it in any way.  Guardian News & Media Limited is not liable for any computer viruses or other material transmitted with or as part of this e-mail. You should employ virus checking software.
 
Guardian News & Media Limited is a member of Guardian Media Group plc. Registered Office: PO Box 68164, Kings Place, 90 York Way, London, N1P 2AP.  Registered in England Number 908396


John Langley

unread,
Jul 3, 2014, 10:58:14 AM7/3/14
to play-fr...@googlegroups.com
This http://www.playframework.com/documentation/2.2.x/api/scala/index.html#play.api.cache.Cache$ 
says
set(key: Stringvalue: Anyexpiration: Duration)(implicit app: Application)Unit
so it looks like it could store a Future because Future is an Any, right? 

However, I believe your point is still valid, that if I store something that is not Serializable into it, then it won't be portable across "application servers" / instances of the Play server, so using the memcached or ehcache implementation would fail. 

Sound right? (THANKS for your pointer!) 

John Langley

unread,
Jul 3, 2014, 11:22:47 AM7/3/14
to play-fr...@googlegroups.com
Thanks, I hadn't seen the spray-caching capability before. I've been pretty focused on using Play, but of course as the two merge... ;^) 

Thanks again. 

Adam Evans

unread,
Jul 3, 2014, 11:23:42 AM7/3/14
to play-fr...@googlegroups.com
I also recommend spray cache. 

Play will cache your future even if it's a failure so if your api call fails the future in the cache would be the exception. Spray-Cache only caches successful futures http://spray.io/documentation/1.2.1/spray-caching/

John Langley

unread,
Jul 3, 2014, 11:31:58 AM7/3/14
to play-fr...@googlegroups.com
To ask a "lazy" question... do you know if spray-caching can be used in Play 2.2.3 application w/out problems? Looks like I might have to check the versions of scala, play, akka and spray with pointers from here: http://spray.io/project-info/current-versions/#current-versions  (Play includes akka, so may pin me to something that doesn't work with a particular version of spray-caching w/out doing a local build of things) 

Foo Lim

unread,
Jul 9, 2015, 6:17:20 PM7/9/15
to play-fr...@googlegroups.com
Is there a way to use Cache.getOrElse with Futures in Play 2.3.x?

Using an Await on the Future seems a bit like brute force.

Thanks!

Naftoli Gugenheim

unread,
Jul 12, 2015, 2:13:20 PM7/12/15
to play-fr...@googlegroups.com

Can you be more specific? Some context seems to be missing.


Will Sargent

unread,
Jul 15, 2015, 3:08:56 PM7/15/15
to play-fr...@googlegroups.com
You can use spray-cache, which works with Future directly:

Foo Lim

unread,
Jul 15, 2015, 4:37:52 PM7/15/15
to play-fr...@googlegroups.com
Is there any more details on how to use spray-caching as a plugin? The
documentation just says:

https://www.playframework.com/documentation/2.3.x/ScalaCache

You can also provide your own implementation via a plug-in.
...
Note: The API is intentionally minimal to allow several implementation
to be plugged. If you need a more specific API, use the one provided
by your Cache plugin.


Thanks!
> You received this message because you are subscribed to a topic in the
> Google Groups "play-framework" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/play-framework/qVDMvqZidpI/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> play-framewor...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/play-framework/CAJmgB60kVQXp5HmSjPHX1fGMaxR-iM9U-j1fdvjhJ_CeJBdF2g%40mail.gmail.com.

Foo Lim

unread,
Jul 15, 2015, 5:04:13 PM7/15/15
to play-fr...@googlegroups.com
Well, others on this thread have said you shouldn't a Future in the
cache but the value, but the only way to get the value is to Await the
Future to end or am I missing something here?

</psuedocode>
val maybeUser: Option[User] = Cache.getAs[User]("user.key")

// if maybeUser is None,
val futureUser: Future[User] = Db.getAFutureUser("user.key")
val user: User = Await.result(futureUser, 5 seconds)
Cache.set("user.key", user)
</psuedocode>

Rather than:

val user: User = Cache.getOrElse("user.key") {
???
}


Thanks
> You received this message because you are subscribed to a topic in the
> Google Groups "play-framework" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/play-framework/qVDMvqZidpI/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> play-framewor...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/play-framework/CANpg8PAYLThvxKykrAXc1Zw4tmf7zihHcyUQHveXGYOuQSE38g%40mail.gmail.com.

James Ward

unread,
Jul 16, 2015, 1:00:02 PM7/16/15
to play-fr...@googlegroups.com
You don't need to use a blocking Await.  Just do:
futureUser.foreach { user => Cache.set("user.key", user) }

That will set the user in the cache once the future completes.

Naftoli Gugenheim

unread,
Jul 17, 2015, 12:51:33 AM7/17/15
to play-fr...@googlegroups.com

What's wrong with storing the Future in the cache?


Adam Evans

unread,
Jul 17, 2015, 6:46:40 AM7/17/15
to play-fr...@googlegroups.com
You will suffer from Thundering herds doing this? Each request while the future isn't resolved ie Cache.set hasn't yet been called so it's a cache miss will cause `futureUser.foreach { user => Cache.set("user.key", user) }` to be evaluated again if it's in the getOrElse block.


Re nafg "What's wrong with storing the Future in the cache?":
If the future fails to resolve ie has a failure you have a failed future in the cache, if your cache ttl is 1 hour your serving up an error for 1 hour unless the item is purged. If it's a short ttl (seconds/minutes) you may be able to live with it, I'd think for most use cases only caching a successful future is what most people want to do.

Spray-Cache only caches successful futures and resolves thundering heards. If you only want a local cache not a shared distributed cache it works well and easy to setup. Don't try hooking it in to the play cache framework, use as advertised on the Spracy-Cache docs.

James Ward

unread,
Jul 17, 2015, 12:22:42 PM7/17/15
to play-fr...@googlegroups.com
Futures aren't serializable. And even though it might work to put a Future in an in-memory cache, that limits your options if you later want to move that cache somewhere else.

Likely Spray-Cache uses an actor which is the best way to deal with the Thundering herds. I handle this exact situation on webjars.org with just a raw Actor:
https://github.com/webjars/webjars/blob/master/app/utils/MavenCentral.scala#L118-L140
Reply all
Reply to author
Forward
0 new messages