0

I have some code that looks roughly like this:

Completable handle(Observable<Object> inbound) {
  return inbound.buffer(1, TimeUnit.Second, 250)
    .filter(l -> !l.isEmpty())
    .flatMapToCompletable(this::sendToClient);
}

Completable sendToClient(List<Object> list) {
  // call IO asynchronously
}

inbound is a cold observable that is producing in a standard while loop (but on another Thread!). While not disposed, fetch some data and call onNext().

The issue I face is that sendToClient is too "slow", it can't keep up with the speed at which inbound is producing data. It's an async operation that is essentially queuing the calls to the client in memory somewhere (don't have access to this code) and eventually filling the heap.

I need a way to figure out a way to get inbound to stop producing when these calls start to stack up. Is there a way to achieve this using inbuild operators?

Cheetah
  • 13,785
  • 31
  • 106
  • 190
  • Instead of stop producing, perhaps don't attempt to send if there is another IO call in progress (or some pending count > threshold)? – Andrew S Jan 21 '22 at 15:22
  • @AndrewS - I don't have access into that code. I don't know how much is queued. – Cheetah Jan 21 '22 at 15:25
  • You could consider using `Flowable.generate` that does offer backpressure, however, the timed `buffer` would remain an issue as it unbounds the flow. If you can just use the size-bound `buffer` alternative, that would improve this latter situation. – akarnokd Jan 21 '22 at 15:28

1 Answers1

0

I would probably suggest creating a thread pool to handle the sendToClient operations. This can support having a queue of requests waiting to be handled, but you can also specify behavior if the queue is full (ie, too much back pressure).

Take a look at java.util.concurrent.ThreadPoolExecutor

Steve
  • 1
  • 1