https://kotlinlang.org logo
Title
c

christophsturm

11/29/2021, 8:59 AM
is there a kotlin pool library like commons-pool, maybe one that uses coroutines?
g

Gerard Klijs

11/29/2021, 9:18 AM
Not sure what you are looking for, you can a Thead pool into a coroutine ditpatcher like https://github.com/gklijs/kotlin-coroutines-demo/blob/fd90929e310e1d20c95c3a6ec8836500eb605274/src/main/kotlin/tech/gklijs/Util.kt#L76.
c

christophsturm

11/29/2021, 9:48 AM
i want a generic pool not a thread pool.
usually i just use commons-pool but its time for a kotlin replacement, that does not block
g

Gerard Klijs

11/29/2021, 9:55 AM
But what do you want to do?
c

christophsturm

11/29/2021, 9:57 AM
main use is for throttling, i have a test runner that runs tests in parallel. but i don’t want to spin up more than 10 docker containers.
(as an example)
or a redis container can contain 16 databases so i can run 16 test that need it in parallel
s

Scott Christopher

11/29/2021, 9:58 AM
If you can wait until 1.6.0, the new
CoroutineDispatcher.limitedParallelism
would be useful. In the interim, I make use of a bounded Channel for a similar use case.
c

christophsturm

11/29/2021, 9:59 AM
guys it has nothing to do with threads
its a pool for resources
s

Scott Christopher

11/29/2021, 9:59 AM
I realise that
c

christophsturm

11/29/2021, 10:00 AM
ok how would you do it with limited paralelism?
i was thinking just a suspend method getInstance that blocks until a docker container is free and then returns one
docker container is just an example of a heavy weight resource
s

Scott Christopher

11/29/2021, 10:01 AM
Then a bounded Channel is probably good enough for that
You can read some of the examples in about
limitedParallelism
here: https://github.com/Kotlin/kotlinx.coroutines/issues/2919
c

christophsturm

11/29/2021, 10:03 AM
how would i reuse resources that become free with a bounded channel?
You would need to have something wrapping it that returns them to the channel once they're released
c

christophsturm

11/29/2021, 10:05 AM
i have used channels for throttling before. just not sure if its also optimal for pooling
but thanks for the inspiration
👍 1
r

Robert Jaros

11/29/2021, 10:06 AM
Perhaps look for something reactive (e.g. https://github.com/reactor/reactor-pool) and use coroutines-reactor.
c

christophsturm

11/29/2021, 10:10 AM
thanks will look at that too. but i guess a pool is really something very simple so no need for any dependencies
but good inspiration about the reactiveness
imo pooling is a different api than a channel but i can always use a channel in the implementation
s

Scott Christopher

11/29/2021, 10:39 AM
Yeah, I was just thinking something simple along the lines of this, though obviously tweaked depending on what features of the pool you need
class Pool<A> private constructor(private val channel: Channel<A>) {

  suspend fun borrow(fn: suspend (A) -> Unit) {
    val item = channel.receive()
    fn(item)
    channel.send(item)
  }

  companion object {
    suspend fun <A> create(size: Int, factory: suspend () -> A): Pool<A> {
      val channel = Channel<A>(size)
      repeat(size) {
        channel.send(factory())
      }
      return Pool(channel)
    }
  }
}
👍 1
n

Nick Allen

11/29/2021, 8:43 PM
That already exists. It's called Semaphore. See
withPermit
extension method.
c

christophsturm

11/30/2021, 7:32 AM
That works for throttling but not pooling, right?