Guava を使用してデータを入力していますが、1 分ごとにLoadingCacheすべてのエントリを削除したいと考えています。LoadingCache
public class MetricHolder {
private final ExecutorService executor = Executors.newFixedThreadPool(2);
private final LoadingCache<String, AtomicLongMap<String>> clientIdMetricCounterCache =
CacheBuilder.newBuilder().expireAfterWrite(1, TimeUnit.MINUTES)
.removalListener(RemovalListeners.asynchronous(new SendToDatabase(), executor))
.build(new CacheLoader<String, AtomicLongMap<String>>() {
@Override
public AtomicLongMap<String> load(String key) throws Exception {
return AtomicLongMap.create();
}
});
private static class Holder {
private static final MetricHolder INSTANCE = new MetricHolder();
}
public static MetricHolder getInstance() {
return Holder.INSTANCE;
}
private MetricHolder() {}
public void increment(String clientId, String name) throws ExecutionException {
clientIdMetricCounterCache.get(clientId).incrementAndGet(name);
}
public LoadingCache<String, AtomicLongMap<String>> getClientIdMetricCounterCache() {
return clientIdMetricCounterCache;
}
private static class SendToDatabase implements RemovalListener<String, AtomicLongMap<String>> {
@Override
public void onRemoval(RemovalNotification<String, AtomicLongMap<String>> notification) {
String key = notification.getKey();
AtomicLongMap<String> value = notification.getValue();
System.out.println(key);
System.out.println(value);
// sending these key/value to some other system
}
}
}
incrementマルチスレッドの方法で、コード内のさまざまな場所からメソッドを呼び出しています。そのため、1 分間で多くのメトリックが に入力されclientIdMetricCounterCacheます。ここで、これらすべてのメトリックを 1 分ごとに確実にドロップし、それらすべてのメトリックをデータベースに送信したいと考えています。
私の場合、incrementメソッドへの書き込みが非常に遅い場合がありますが、それでも1分ごとにすべてのエントリを削除したいのですが、このキャッシュで読み取りをまったく行っておらず、書き込みを行ってから、それらのレコードを送信して削除します他のシステム。以下は、Guava wikiで見たものです
CacheBuilder で構築されたキャッシュは、クリーンアップを実行せず、値を「自動的に」削除したり、値の有効期限が切れた直後に削除したり、そのようなものを削除したりしません。代わりに、書き込み操作中、または書き込みがまれな場合は時折の読み取り操作中に少量のメンテナンスを実行します。
では、どのように機能しexpireAfterWriteますか?1分ごとに実行され、そこにあるすべてのエントリclientIdMetricCounterCacheを削除し、1分後に再び起動して同じキャッシュからすべてのエントリを削除し、そのように続行するスケジューラのように機能しますか? ウィキを読んだ後、そのように機能するとは思えません。そうでない場合、書き込みがしばらくの間まれになる可能性があるため、これらのレコードを1分ごとに確実にドロップし、他のシステムに送信するにはどうすればよいですか?
Guava TimeLimiterインターフェイスを使用する必要があるように見えますか、SimpleTimeLimiterまたはScheduledExecutorService呼び出しを確実にタイムアウトしてからエントリをドロップする必要があるように見えますか? はいの場合、誰かが私の現在の例でこれがどのように機能するかの例を提供できますか?