https://kotlinlang.org logo
#getting-started
Title
# getting-started
s

Slackbot

12/04/2023, 4:38 AM
This message was deleted.
w

Wout Werkman

12/04/2023, 7:56 AM
Here is a suggestion for a method that chunks every x milliseconds.
Copy code
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds

suspend fun main() {
    val flowThatDoesWorkForever = flow { while (true) emit(doWork()) }
    flowThatDoesWorkForever
        .chunkedEvery(50.milliseconds)
        .collect { chunk ->
            println(chunk)
        }
}

private fun <T> Flow<T>.chunkedEvery(interval: Duration): Flow<List<T>> = channelFlow {
    val list = mutableListOf<T>()
    val job = launch {
        while (true) {
            delay(interval)
            channel.send(synchronized(list) {
                list.toList().also { list.clear() }
            })
        }
    }
    collect { newItem ->
        synchronized(list) {
            list.add(newItem)
        }
    }
    job.cancel()
}

suspend fun doWork() : Int = (1..10).random().also { delay(it.milliseconds) }
a

Alessandro Tagliapietra

12/05/2023, 1:27 AM
sorry I think I didn't explain it properly, or maybe I don't understand your code, I need something that chunks some calls (in my case from spring controller actions), sends them all together to a single doWork call, then return each of the results to each original controller action threaad
right now I came up with something that seems to be working (but is probably not so optimized) that uses a ConcurrentLinkedQueue, ReadWriteLock, DefferdResult and spring scheduled jobs..