[英]Java collection with expiring entries
我需要在指定的時間范圍內跟蹤某些事件,並在事件數量達到一定數量時采取行動。 更詳細地說,我連接到外部服務並提交已確認狀態等於CONF或FAIL的請求。 我需要能夠監視響應以檢測我是否在給定時間范圍內得到異常數量的失敗,例如> 3在最后5秒內失敗,以便我可以檢查錯誤並采取相應措施。 我可以選擇連續3次檢查,但我更喜歡基於時間的方法。
我在閱讀這篇文章后一直在測試Guava的CacheLoader
,但是當緩存中的條目(我只存儲FAIL事件)似乎按預期到期時,對size()
的調用(以確定失敗次數)也包括過期的條目。 如果我沒有誤解事情,這似乎是根據文檔應該如何工作? 有沒有辦法從緩存中獲取“活動”事件的數量?
我想另一種解決方案是使用像Esper這樣的CEP框架,但對於我的簡單需求來說似乎有點過分和麻煩。 有沒有人有一個完全不同的方法來建議這將有助於我的要求? 謝謝
從Cache
獲取確切數量的活動元素需要鎖定整個緩存,這非常昂貴。 您可以使用cleanUp()
方法來確保size
不會意外地計算已被悄悄驅逐的條目。
我不會依賴於此給出確切的結果,但它應該顯着提高結果的准確性。
你可以裝飾一個集合實現來做到這一點。 像這樣的東西:
public class ExpirableArrayList<E> extends ArrayList<E> {
private final Date creation = new Date();
private final long timeToLiveInMs;
public ExpirableArrayList(long timeToLiveInMs, int initialCapacity) {
super(initialCapacity);
this.timeToLiveInMs = timeToLiveInMs;
}
public ExpirableArrayList(long timeToLiveInMs) {
this.timeToLiveInMs = timeToLiveInMs;
}
public ExpirableArrayList(long timeToLiveInMs, Collection<? extends E> c) {
super(c);
this.timeToLiveInMs = timeToLiveInMs;
}
private void expire() {
if (System.currentTimeMillis() - creation.getTime() > timeToLiveInMs) {
clear();
}
}
@Override
public int size() {
expire();
return super.size();
}
@Override
public boolean isEmpty() {
expire();
return super.isEmpty();
}
@Override
public boolean contains(Object o) {
expire();
return super.contains(o);
}
@Override
public Iterator<E> iterator() {
expire();
return super.iterator();
}
@Override
public Object[] toArray() {
expire();
return super.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
expire();
return super.toArray(a);
}
@Override
public boolean add(E e) {
expire();
return super.add(e);
}
@Override
public boolean remove(Object o) {
expire();
return super.remove(o);
}
@Override
public boolean containsAll(Collection<?> c) {
expire();
return super.contains(c);
}
@Override
public boolean addAll(Collection<? extends E> c) {
expire();
return super.addAll(c);
}
@Override
public boolean addAll(int index, Collection<? extends E> c) {
expire();
return super.addAll(index, c);
}
@Override
public boolean removeAll(Collection<?> c) {
expire();
return super.removeAll(c);
}
@Override
public boolean retainAll(Collection<?> c) {
expire();
return super.retainAll(c);
}
@Override
public E get(int index) {
expire();
return super.get(index);
}
@Override
public E set(int index, E element) {
expire();
return super.set(index, element);
}
@Override
public E remove(int index) {
expire();
return super.remove(index);
}
@Override
public int indexOf(Object o) {
expire();
return indexOf(o);
}
@Override
public int lastIndexOf(Object o) {
expire();
return lastIndexOf(o);
}
@Override
public ListIterator<E> listIterator() {
expire();
return listIterator();
}
@Override
public ListIterator<E> listIterator(int index) {
expire();
return listIterator();
}
@Override
public List<E> subList(int fromIndex, int toIndex) {
expire();
return subList(fromIndex, toIndex);
}
}
我認為具有最接近功能的Guava集合是具有有限最大尺寸的MinMaxPriorityQueue 。 您必須按時間順序放置故障事件,並定期檢查第一個和最后一個元素之間的差異以及它是否已滿。
但你真正想要的是一個儀表。 您可以從Coda Hale的Metrics庫中試用這台儀表 。
我沒有使用它,但看起來這可能滿足您的需求
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.