Sunday, December 30, 2018

Memoize a Supplier in Java

I have been doing a lot of integration work of late, interacting with third party APIs. Several of these APIs require a token to be present during certain invocations. These token have a given lifespan but are rate limited. That is to say they may be valid for fifteen minutes, while one might be only be able to create one every five minutes. If it is necessary to invoke the APIs more than once per this five minute interval, then one cannot create a new token prior to every invocation. 

Additional, since the issuance of a new token is in some sense "expensive" and given the timing mismatch, it makes sense to "cache" a valid token for the duration of its lifespan. In order to do this, I memoized the Supplier of this token, that is I wrapped the API call to create the new token in a Supplier and then I memoized this Supplier within a memoizing Supplier.

As a bit of background, the Supplier (functional) interface was introduced in Java version 8. It has a single method ("get") which takes no arguments, but returns an Object of type T, in this case, of type String.

Javadoc reference link: https://docs.oracle.com/javase/8/docs/api/java/util/function/Supplier.html

To memoize this token Supplier, I could create a class that took the delegate Supplier has a constructor argument. Internally, there would be a value object of type T that would contain the result of the invocation of the delegate Supplier. 

public class MemoizingSupplier<T> implements Supplier<T> { 
    final Supplier<T> delegate; 
    private T value; 

    public MemoizingSupplier(final Supplier<T> delegate) { 
        this.delegate = delegate;
    } 
  
    @Override public T get() { 
         if (value == null) { 
             T t = delegate.get(); 
             value = t; 
             return t; 
         } 
         return value;
}}

A better example (and more thread safe version) is found here: https://google.github.io/guava/releases/19.0/api/docs/com/google/common/base/Suppliers.html#memoize(com.google.common.base.Supplier)

As you can see, Guava provides some very convenient memoization utilities that could be used instead of writing your own. In the use case provided above, I wound up using the method memoizeWithExpiration. This memoizing Supplier would expire every ten minutes, ensuring that API invocations would always be able to create a token should they need to.

https://google.github.io/guava/releases/19.0/api/docs/src-html/com/google/common/base/Suppliers.html#line.167


1 comment:

  1. Wild Casino: Play online for free or for real money!
    Play Wild Casino, a game that's 젖탱 been around since 더굿 토토 2010. It's got a lot of hype, including hundreds 룰렛 확률 of awesome games and bonuses 룰렛 테이블 that pay out 무료 슬롯 머신 to you

    ReplyDelete