我网站上的流量可能很重,我想减慢我运行昂贵的清理功能的频率;我也想在后台运行它。
我用removementListener实现了一个缓存,并期望它在创建条目后30秒钟异步运行,但是我发现它要么根本不运行,要么立即运行。当它运行时,我还必须等待清理脚本。我是否误解了缓存和删除侦听器的目的?
@Path("my-endpoint")
public class MyResource{
private static final Cache<String, String> debounceCleaner = CacheBuilder
.newBuilder()
.maximumSize(1000)
.expireAfterWrite(30, TimeUnit.SECONDS)
.removalListener((RemovalListener<String, String>) x-> new Cleaner().clean())
.build();
@PUT
public Response update(){
...
try{
debounceCleaner.get("foo", ()->"bar");
} catch (ExecutionException ex){
throw new IllegalStateException("Unhandled", ex);
}
return Response(...)
答案 0 :(得分:0)
缓存过期不打算用作去抖动器。其他问题也回答了如何不同程度地创建去抖动器。
implementing debounce in Java Deliver the first item immediately, 'debounce' following items
我为此应用编写了一个去抖动器,如下所示:
public class Debouncer {
private final int TIMEOUT = 30000;
private Runnable runnable;
private Thread backgroundRunnerLoop;
private Date lastRun = null;
private Date lastRequest = null;
public Debouncer(Runnable runnable) {
this.runnable = runnable;
this.backgroundRunnerLoop = new Thread(() -> {
while (true) {
try {
Thread.sleep(TIMEOUT);
if (lastRequest != null && (lastRun == null || lastRun.before(DateUtils.addMilliseconds(lastRequest, TIMEOUT)))) {
this.runnable.run();
lastRun = new Date();
}
} catch (Exception ex) {
throw new IllegalStateException("Debouncer loop broke.", ex);
}
}
});
}
public void start() {
if(!backgroundRunnerLoop.isAlive()){
backgroundRunnerLoop.start();
}
}
public void resetTimer() {
lastRequest = new Date();
}
}
我这样实例化
@Path("my-endpoint")
public class MyResource {
private static final Debouncer debouncer = new Debouncer(() -> new Cleaner().run());
public MyResource() {
debouncer.start();
}
@PUT
public Response update(){
// ...
debouncer.resetTimer();
return Response.noContent(...).build();
}
}