Last active
September 11, 2018 02:15
-
-
Save leozc/85e98a6f15d2f707a35f45ec73486c26 to your computer and use it in GitHub Desktop.
FutureCache For Java CompletableFuture - enable enqueue a long running future task into the Future pool, and provide an interface to store and fetch the long running results
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.leozc.FutureCache; | |
import java.util.Objects; | |
import java.util.Optional; | |
import java.util.concurrent.CompletableFuture; | |
import java.util.concurrent.ThreadLocalRandom; | |
import java.util.function.BiConsumer; | |
import java.util.function.BiFunction; | |
import java.util.function.Function; | |
public class FutureCache<T> { | |
private Long ttlms; | |
/** | |
* | |
* @param ttlms how long a ticket should live for, usually this maps to the default object ttl of the storage. - usually the ttl is way larger than the time needed to perform the task | |
*/ | |
public FutureCache(Long ttlms) { | |
this.ttlms = ttlms; | |
} | |
/** | |
* Dispatch the completableFuture and wire it with a Store function and return a ticket for polling | |
* @param task a completable future indicate a long running computation process that produce T | |
* @param store a lambda to store result of task to a persistent store - which usually accessible by multiple process. | |
* @return | |
*/ | |
public Ticket getTicket(CompletableFuture<T> task, BiFunction<String, T, T> store){ | |
String key = String.valueOf(ThreadLocalRandom.current().nextInt(0, Integer.MAX_VALUE)); | |
long now = System.currentTimeMillis(); | |
BiConsumer<? super T, ? super Throwable> biConsumer = (BiConsumer<T, Throwable>) (t, throwable) -> { | |
if (throwable == null) { | |
store.apply(key, t); | |
} | |
}; | |
// TODO: emit metrics to calculate the time takes for tasks | |
task.whenComplete(biConsumer); | |
return new Ticket(key, now, now + ttlms); | |
} | |
public Optional<T> getReady(String key, Function<String, T> lookupStore){ | |
T t = lookupStore.apply(key); | |
if (Objects.isNull(t)) | |
return Optional.empty(); | |
else | |
return Optional.of(t); | |
} | |
class Ticket{ | |
private String key; | |
private Long issueTime; | |
private Long ttl; | |
public Ticket(String key, Long issueTime, Long ttl) { | |
this.key = key; | |
this.issueTime = issueTime; | |
this.ttl = ttl; | |
} | |
public String getKey() { | |
return key; | |
} | |
/** | |
* The | |
* @return timestamp in ms | |
*/ | |
public Long getIssueTime() { | |
return issueTime; | |
} | |
/** | |
* Get how long the result will store on the server side | |
* @return the number of ms | |
*/ | |
public Long getTtl() { | |
return ttl; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment