com.ybrikman.ping.scalaapi

dedupe

package dedupe

Visibility
  1. Public
  2. All

Type Members

  1. class BeforeAndAfterFilter extends Filter

    A filter that takes two parameters--a before function and an after function--and guarantees the before function is executed before the rest of the filter chain executes and the after function is executed after the rest of the filter chain (no matter what error may have been thrown).

  2. class Cache[K, V] extends AnyRef

    A Scala wrapper for a Java's ConcurrentHashMap (CHM).

    A Scala wrapper for a Java's ConcurrentHashMap (CHM). Exposes the basic underlying methods of CHM and adds a getOrElseUpdate(key, value) method that lazily evaluates the value parameter only if the key is not already present in the cache.

    You may be asking, why not just use Scala's ConcurrentMap interface, which already has a getOrElseUpdate method?

    val cache = new ConcurrentHashMap().asScala cache.getOrElseUpdate("foo", "bar") // BAD idea

    The answer is because this method is inherited from the MapLike trait, and is NOT a thread safe (atomic) operation!

    The strategy used in the class below is to wrap all values with a LazyWrapper class that only evaluates the value when explicitly accessed. In the getOrElseUpdate method, we avoid accessing the passed in value unless we know it was the one actually inserted into the cache.

    For more info, see: http://boundary.com/blog/2011/05/

    TODO: investigate if boundary's NonBlockingHashMap is as good as they say it is (and what tests they have to prove it).

    TODO: Java-friendly API

    K
    V

  3. class CacheFilter[K, V] extends BeforeAndAfterFilter

    Any time you use the DedupingCache, you must add this CacheFilter to your filter chain.

    Any time you use the DedupingCache, you must add this CacheFilter to your filter chain. This filter will initialize the cache for each incoming request and cleanup the cache after you're done processing the request. To avoid memory leaks, you want to be sure this filter runs on every single request, so it's a good idea to make it the very first one in the filter chain, so no other filter can bypass it.

    K
    V

  4. class CacheNotInitializedException extends RuntimeException

  5. class DedupingCache[K, V] extends AnyRef

    A cache you can use to de-dupe expensive calculations to ensure that the same calculation happens at most once while processing any incoming request.

    A cache you can use to de-dupe expensive calculations to ensure that the same calculation happens at most once while processing any incoming request. For example, imagine you get an incoming request to /foo, and to render this page, you have to make a dozen calls to remote services (e.g. a profile service, a search service, etc) using REST over HTTP. You can use the DedupingCache to ensure you don't make the same exact call more than once (e.g. fetch the exact same profile multiple times) by running all the calls through this client. You would use the URL of the REST call as the key and the Future returned from the call as the value:

    val remoteUrl = "http://example.com/some/remote/service" val future: Future[Response] = dedupingCache.get(remoteUrl, WS.url(remoteUrl).get())

    While processing any incoming request, using the code above ensures that you will not make multiple calls to the exact same remoteUrl; any duplicates will just return a Future object that is already in the cache.

    You should only use the DedupingCache for data that is safe to cache. For example, HTTP GET calls are usually safe to cache since they should be idempotent, but HTTP POST calls are not safe to cache. Also, you need to add the CacheFilter to your filter chain so that it can clean up the cache after you're done processing an incoming request. Otherwise, you'll have a memory leak.

    K

    The type to use for keys. This type must define an equals and hashCode method. For example, if you're making REST over HTTP calls, the HTTP URL is a good key.

    V

    The type of value that will be returned. For example, if you're making REST over HTTP calls using Play's WS library, a Future[Response] might be a good type for the value.

  6. class LazyWrapper[T] extends AnyRef

    A wrapper that avoids evaluating the value until explicitly accessed by calling either .value, .equals, .hashCode, or .toString.

    A wrapper that avoids evaluating the value until explicitly accessed by calling either .value, .equals, .hashCode, or .toString.

    T

Value Members

  1. object Cache

  2. object JavaFunctionHelper

Ungrouped