aboutsummaryrefslogtreecommitdiff
path: root/src/main/scala/xyz/driver/core/Refresh.scala
diff options
context:
space:
mode:
authorJakob Odersky <jakob@odersky.com>2018-08-24 14:37:50 -0700
committerGitHub <noreply@github.com>2018-08-24 14:37:50 -0700
commit31e2cdd834c3be3d59bc23ee2c4eff7874d80159 (patch)
treefb8044a9f6dcaf27b43d4c7add2e4f70911487bd /src/main/scala/xyz/driver/core/Refresh.scala
parentdf1a2f7fcbdd85ac84162cf8eae8cdb6bb25cbb5 (diff)
downloaddriver-core-31e2cdd834c3be3d59bc23ee2c4eff7874d80159.tar.gz
driver-core-31e2cdd834c3be3d59bc23ee2c4eff7874d80159.tar.bz2
driver-core-31e2cdd834c3be3d59bc23ee2c4eff7874d80159.zip
Upgrade sbt-settings to major version 2 (#201)
This will affect development workflow: instead of running `sbt release` to tag and publish a new version, the release process is now as follows: 1. Create a git tag on a revision that should be published. The tag must be in the format `v[0-9].*` 2. Push the tag to GitHub `git push --tags` 3. CI will build that tag and publish the resulting binary to our artifactory Since the new sbt settings do not enable advanced or risky language features globally anymore (such as higher kinds, reflective calls and implicit conversions), the other changes in this PR either import language features locally or refactor the code to avoid using them entirely.
Diffstat (limited to 'src/main/scala/xyz/driver/core/Refresh.scala')
-rw-r--r--src/main/scala/xyz/driver/core/Refresh.scala20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/main/scala/xyz/driver/core/Refresh.scala b/src/main/scala/xyz/driver/core/Refresh.scala
index ca28da7..e66b22f 100644
--- a/src/main/scala/xyz/driver/core/Refresh.scala
+++ b/src/main/scala/xyz/driver/core/Refresh.scala
@@ -8,8 +8,8 @@ import scala.concurrent.duration.Duration
/** A single-value asynchronous cache with TTL.
*
- * Slightly adapted from Twitter's "util" library
- * https://github.com/twitter/util/blob/ae0ab09134414438af9dfaa88a4613cecbff4741/util-cache/src/main/scala/com/twitter/cache/Refresh.scala
+ * Slightly adapted from
+ * [[https://github.com/twitter/util/blob/ae0ab09134414438af9dfaa88a4613cecbff4741/util-cache/src/main/scala/com/twitter/cache/Refresh.scala Twitter's "util" library]]
*
* Released under the Apache License 2.0.
*/
@@ -17,15 +17,27 @@ object Refresh {
/** Creates a function that will provide a cached value for a given time-to-live (TTL).
*
+ * It avoids the "thundering herd" problem if multiple requests arrive
+ * simultanously and the cached value has expired or is unset.
+ *
+ * Usage example:
* {{{
* def freshToken(): Future[String] = // expensive network call to get an access token
- * val getToken: Future[String] = Refresh.every(1.hour)(freshToken())
+ * val getToken: () => Future[String] = Refresh.every(1.hour)(freshToken())
*
* getToken() // new token is issued
* getToken() // subsequent calls use the cached token
* // wait 1 hour
* getToken() // new token is issued
- * }}} */
+ * }}}
+ *
+ * @param ttl Time-To-Live duration to cache a computed value.
+ * @param compute Call-by-name operation that eventually computes a value to
+ * be cached. Note that if the computation (i.e. the future) fails, the value
+ * is not cached.
+ * @param ec The execution context in which valeu computations will be run.
+ * @return A zero-arg function that returns the cached value.
+ */
def every[A](ttl: Duration)(compute: => Future[A])(implicit ec: ExecutionContext): () => Future[A] = {
val ref = new AtomicReference[(Future[A], Instant)](
(Future.failed(new NoSuchElementException("Cached value was never computed")), Instant.MIN)