I'm working with Akka (version 2.4.17
) to build an observation Flow in Java (let's say of elements of type <T>
to stay generic).
My requirement is that this Flow should be customizable to deliver a maximum number of observations per unit of time as soon as they arrive. For instance, it should be able to deliver at most 2 observations per minute (the first that arrive, the rest can be dropped).
I looked very closely to the Akka documentation, and in particular this page which details the built-in stages and their semantics.
So far, I tried the following approaches.
With
throttle
andshaping()
mode (to not close the stream when the limit is exceeded):Flow.of(T.class) .throttle(2, new FiniteDuration(1, TimeUnit.MINUTES), 0, ThrottleMode.shaping())
With
groupedWith
and an intermediary custom method:final int nbObsMax = 2; Flow.of(T.class) .groupedWithin(Integer.MAX_VALUE, new FiniteDuration(1, TimeUnit.MINUTES)) .map(list -> { List<T> listToTransfer = new ArrayList<>(); for (int i = list.size()-nbObsMax ; i>0 && i<list.size() ; i++) { listToTransfer.add(new T(list.get(i))); } return listToTransfer; }) .mapConcat(elem -> elem) // Splitting List<T> in a Flow of T objects
Previous approaches give me the correct number of observations per unit of time but these observations are retained and only delivered at the end of the time window (and therefore there is an additional delay).
To give a more concrete example, if the following observations arrives into my Flow:
[Obs1 t=0s] [Obs2 t=45s] [Obs3 t=47s] [Obs4 t=121s] [Obs5 t=122s]
It should only output the following ones as soon as they arrive (processing time can be neglected here):
Window 1: [Obs1 t~0s] [Obs2 t~45s] Window 2: [Obs4 t~121s] [Obs5 t~122s]
Any help will be appreciated, thanks for reading my first StackOverflow post ;)