4

Imagine we are reading messages from a message queue and on receive pushing them for processing into a threadpool. There are limited number of threads, so if all the threads are busy, we'll have natural backpressure.

How this can be solved in Kotlin coroutine world? If we'll create a coroutine for each incoming message, we can very fast end up with Out of memory errors (e.g if each task requires to load some data from DB) and other issues.

Are there any mechanisms or patterns to solve this problem?

silent-box
  • 1,649
  • 3
  • 21
  • 40
  • Unless you use a custom blocking queue for the thread pool, ypu won't have any backpressure, either. It takes detailed work at every step. – Marko Topolnik Dec 12 '18 at 07:57
  • @MarkoTopolnik ThreadPoolExecutor has an embedded queue, and you can use CallerRunsPolicy to gracefully reject over-capacity tasks. This basically gives you backpressure out of the box – silent-box Dec 12 '18 at 23:30
  • You have to specifically supply a bounded queue to it. The default, if constructed via `Executors`, is an unbounded queue. Also, "caller runs" policy is a blocking one; since you're into coroutines I thought you were after non-blocking behavior. – Marko Topolnik Dec 13 '18 at 06:40

1 Answers1

3

One way to solve the issue, is to create a Channel and send your data onto it. Other threads can put a consumeEach on the channel to receive data from it. The channel's capacity can be tweaked to your threading needs.

Fan-out and Fan-in examples in the coroutines docs can be helpful too.

Adib Faramarzi
  • 3,798
  • 3
  • 29
  • 44