imagine that we have a data processing pipeline, consists of 3 steps
val finalValue=fn3(fn2(fn1(originalValue)))
however fn2
is cpu intensive, thus we want to parallelize it
/-> fn2(on thread1) --\
fn1(originalValue) -+-> fn2(on thread2) --+-> fn3(...) -->
\-> fn2(on thread3) --/
which is the best approach?
I can think of two approaches:
use two channels to fan-out and fan-in, but this doesn’t preserve the source data(originalValue
) order, so we have to buffer, reorder, potentially block to provide back pressure… too complex
another approach is to use LMAX disruptor, a famous java library: LMAX Disruptor
but this adds another dependency and is not kotlin friendly(similarly we can use java stream
, we also have to consider how to integrate into stream
’s rather complex internal apis for managing parallelisms/stop infinite streams).
most importantly, disruptor excels in low latency high throughput, it adds code/config complexity for this, but not all project need them all. I’m not concerned too much about latency, as I may later refactor the code to distribute fn2
not only on cpu cores(threads) but also on clusters(different machines). custom data processing pipeline with different performance targets, may not be suitable on spark/flink