Size: a a a

Kotlin Community

2020 June 18

RI

Ruslan Ibragimov in Kotlin Community
Boris Vanin
есть какой-то простой способ запустить тонну корутин параллельно и когда получил первый резульатат остальные отменить?
select?
источник

RI

Ruslan Ibragimov in Kotlin Community
suspend fun <T> List<suspend CoroutineScope.() -> T>.race(): T {
   val job = Job()
   return select {
       forEach { task ->
           GlobalScope
               .async(job) { task() }
               .onAwait {
                   job.cancel()
                   it
               }
       }
   }
}
источник

RI

Ruslan Ibragimov in Kotlin Community
Честно говоря не уверен на счет cancel, возможно тут придется что-то похитрее делать
источник

RI

Ruslan Ibragimov in Kotlin Community
Вроде адекватно работает:

suspend fun main() {
   val s = listOf<suspend CoroutineScope.() -> String>(
       { delay(3000); println("first"); "first"; throw RuntimeException("Test") },
       { delay(1000); println("second"); "second" },
       { delay(2000); println("third"); "third" }
   ).race()

   delay(4000)

   println(s)
}
источник

LS

Lev Shagalov in Kotlin Community
Andrew Mikhaylov
ЯННП. В первом случае вы создаёте скоуп, выполняете в нём пустую лямбду, и кладёте в asd джобу, которая по идее сразу должна быть завершённой, во втором предположительно определяете экстеншн на CoroutineScope (правда с не совсем правильным синтаксисом).
А почему во втором случае не правильный синтаксис?
fun CoroutineScope.asd  {}
А ну () забыл?)
источник

AM

Andrew Mikhaylov in Kotlin Community
Lev Shagalov
А почему во втором случае не правильный синтаксис?
fun CoroutineScope.asd  {}
А ну () забыл?)
Ну да, я о пустых круглых скобках :)
источник

LS

Lev Shagalov in Kotlin Community
Как сделать потребление сообщений из канала пачками (сразу все имеющиеся сообщения)?
https://pl.kotl.in/gWvbXGBLa
источник

VP

Vladimir Petrakovich in Kotlin Community
Boris Vanin
есть какой-то простой способ запустить тонну корутин параллельно и когда получил первый резульатат остальные отменить?
Готового решения вроде нет, а я бы сделал как-то так
https://pl.kotl.in/H1jFhCEOQ
источник

LS

Lev Shagalov in Kotlin Community
suspend fun CoroutineScope.handle(message: Message)
Я правильно понимаю, если стоит suspend, то CoroutineScope ресивер особо то и не нужен?

Upd: прочитал https://medium.com/@elizarov/explicit-concurrency-67a8e8fd9b25
источник

LS

Lev Shagalov in Kotlin Community
А что если я в suspend хочу таки launch запустить?
источник

IO

Iaroslav Orlov in Kotlin Community
а зачем? это не нужно в большинстве случаев
источник

IO

Iaroslav Orlov in Kotlin Community
withContext иногда нужен, но билдеры реже
источник

АО

Алексей Овсянников... in Kotlin Community
Lev Shagalov
А что если я в suspend хочу таки launch запустить?
Один из главных принципов - пока тебе явно не надо запустить что-то параллельно, делай всё максимально последовательно. Ну то есть все функции с потенциально работой в отдельной корутине должны быть suspend fun без запуска корутины внутри. Если ну очень хочется - coroutineScope { launch { … } }
источник

АО

Алексей Овсянников... in Kotlin Community
Алексей Овсянников
Один из главных принципов - пока тебе явно не надо запустить что-то параллельно, делай всё максимально последовательно. Ну то есть все функции с потенциально работой в отдельной корутине должны быть suspend fun без запуска корутины внутри. Если ну очень хочется - coroutineScope { launch { … } }
Ну то есть функции сами по себе - это последовательные кусочки, которые ты будешь запускать параллельно в месте вызова этой функции
источник

BV

Boris Vanin in Kotlin Community
Ruslan Ibragimov
suspend fun <T> List<suspend CoroutineScope.() -> T>.race(): T {
   val job = Job()
   return select {
       forEach { task ->
           GlobalScope
               .async(job) { task() }
               .onAwait {
                   job.cancel()
                   it
               }
       }
   }
}
У меня тоже что-то типа такого получилось, думал может есть какой-то шорткат с флоу или типа того
источник

LS

Lev Shagalov in Kotlin Community
Алексей Овсянников
Один из главных принципов - пока тебе явно не надо запустить что-то параллельно, делай всё максимально последовательно. Ну то есть все функции с потенциально работой в отдельной корутине должны быть suspend fun без запуска корутины внутри. Если ну очень хочется - coroutineScope { launch { … } }
А где эти принципы почитать?
источник

I

In7 in Kotlin Community
Lev Shagalov
А где эти принципы почитать?
Стив МакКонел -  Совершенный код или Чистый код Роберта Мартина например.
источник

АО

Алексей Овсянников... in Kotlin Community
Lev Shagalov
А где эти принципы почитать?
Там, кажется, даже в доке об этом было
источник

LS

Lev Shagalov in Kotlin Community
Звучит так, что не надо запускать корутины из корутин.
источник

АО

Алексей Овсянников... in Kotlin Community
источник