Java Collection with Expiring Entries

I need to track certain events for a certain period of time and act if the number of events reaches a certain number. In more detail, I connect to an external service and send requests that are confirmed by the status equal to CONF or FAIL. I need to be able to track responses to detect if I get an unusual number of crashes in a given period of time, for example. > 3 does not work in the last 5 seconds, so I can check for errors and act accordingly. I could alternatively verify that 3 is unsuccessful in a string, but I prefer a time based approach.

I tested the Guava CacheLoader after reading this post , but while the entries (I only store FAIL events) in the cache expire, as expected, the call to size() (to determine the number of failures) also includes the expired entries. It seems like this should work as per the documentation if I didn't get it wrong? Is there a way to get the number of active events from the cache?

I suppose an alternative solution is to use a CEP framework like Esper, but it seems redundant and cumbersome for my simple needs. Does anyone have a completely different approach to suggest that will ease my requirement? Thanks

+4
source share
4 answers

Getting the exact number of active items from Cache will require blocking the entire cache, which is extremely expensive. You may be able to use the cleanUp() method to make sure that size does not accidentally count records that have been quietly evicted.

I would not depend on this, giving you accurate results, but it should significantly improve the accuracy of the results.

+6
source

I think the Guava collection with the closest functionality to what you want is a MinMaxPriorityQueue with a limited maximum size. You will need to place the failure events in chronological order and periodically check the difference between the first and last element and completeness.

But what you basically want is a meter. You can try this counter from the Coda Hale Metrics library.

+1
source

You can decorate the collection implementation to do this. Something like that:

 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); } } 
+1
source

I have not used it, but it looks like this one can satisfy your needs.

0
source

Source: https://habr.com/ru/post/1398038/


All Articles