A big concern, as I understand it, is how to allow some elements to expire after a certain period. I had a similar requirement, and I created a message class that implemented the Delayed Interface . This class contained everything I needed for a message, and (via the Delayed interface) told me when it expired.
I used instances of this object in a parallel collection, you could use ConcurrentMap as it will allow you to use these objects with an integer key.
I collected the collection once so often, removing the elements whose delay passed. We test for expiration using the getDelay method of the Delayed interface:
message.getDelay(TimeUnit.MILLISECONDS);
I used a regular thread that will sleep for a period and then reaps expired items. It was not important in my requirements that the items be deleted as soon as their delay has expired. It seems like you have the same flexibility.
If you needed to remove items as soon as their delay expired, instead of having a hibernate set period in your harvest stream, you would sleep for delaying the message that will expire first.
Here is my delayed message class:
class DelayedMessage implements Delayed { long endOfDelay; Date requestTime; String message; public DelayedMessage(String m, int delay) { requestTime = new Date(); endOfDelay = System.currentTimeMillis() + delay; this.message = m; } public long getDelay(TimeUnit unit) { long delay = unit.convert( endOfDelay - System.currentTimeMillis(), TimeUnit.MILLISECONDS); return delay; } public int compareTo(Delayed o) { DelayedMessage that = (DelayedMessage) o; if (this.endOfDelay < that.endOfDelay) { return -1; } if (this.endOfDelay > that.endOfDelay) { return 1; } return this.requestTime.compareTo(that.requestTime); } @Override public String toString() { return message; } }
source share