简体   繁体   中英

Is the play.api.cache.Cache.getOrElse function Thread safe?

I am using that method to cache the result of a function that use an http call. My code looks like this, and that http is possibly gready.

  def myData: Iterable[String] = {
    Cache.getOrElse[Iterable[String]](cacheKey, cacheExpiration)(Await.result(myHttpCallFunction(), Duration.apply(500, TimeUnit.MILLISECONDS)))
  }

I used to have it as

  val myData: Iterable[String] = Await.result(myHttpCallFunction(), Duration.apply(500, TimeUnit.MILLISECONDS))

is my code thread safe now? Or should I do something else. I must say I am quite new to scala and I am not quite intimate with its inner working. If it isn't thread safe: How can I make it so?

According to the source code, it is not thread safe regardless of cache implementation.

def getOrElse[A](key: String, expiration: Int = 0)(orElse: => A)(implicit app: Application, m: ClassManifest[A]): A = {
    getAs[A](key).getOrElse {
      val value = orElse
      set(key, value, expiration)
      value
    }
  }

Think about this scenario:

  1. first request comes in at timestamp 100ms
  2. key does not exist in cache, so orElse is executed to initialise cache value, let's say it will take 50ms to complete
  3. second request come in at timestamp 120ms for same key
  4. because the first orElse has not yet completed, there is no value found in cache, so orElse is executed again to initialise cache value
  5. on timestamp 150ms, first orElse returned and saved to the map
  6. on timestamp 160ms, third request come in for same key. Cached value will be returned immediately
  7. on timestamp 170ms, second orElse returned. Even value is already cached, cache will be overwritten

Therefore, play Cache plugin is good for serving static data which could take quite long to initialise. In this case usually multiple initialisation is not a problem.

Don not use Cache to maintain global variable.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM