https://kotlinlang.org logo
Title
t

taer

01/24/2020, 10:54 PM
Is there a better way to "yield" in a suspend function other than a delay(1)? I have this loop
private suspend fun poll2() {
    while (true) {
      consumer.poll(Duration.ofMillis(500))
        .forEach {
            channel.send("ping")
          }
        }
    }
  }
Channel is a kotlin Channel. If consumer.poll returns empty, the foreach doesn't execute. So we don't ever execute any suspendable code, so this loops forever, not giving back the thread to the coroutine. If I add a
delay(1)
immediately preceeding the poll, then other coroutines get a chance to run. Is there a cheaper alternative to an arbitrary 1ms delay? BTW, this is an attempt to wrap a Kafka consumer output into a easier to consume Kotlin channel.
o

octylFractal

01/24/2020, 10:54 PM
yield()
?
2
t

taer

01/24/2020, 10:56 PM
haha.. i always assumed that was for generatory things
z

Zach Klippenstein (he/him) [MOD]

01/24/2020, 10:58 PM
It is, but only in the context of the
sequence { }
builder. Confusing, I know.
t

taer

01/24/2020, 10:59 PM
Awesome. That worked perfectly. And reminded me that a sequence might actually work better for this use case vs the current channel.
o

octylFractal

01/24/2020, 11:28 PM
if you want to retain coroutine lib. suspension features, you'll want to use
Flow
instead
sequence is only internally suspend, it doesn't use suspend outside of the builder
b

bdawg.io

01/25/2020, 2:25 AM
yield()
is a generic suspend function that can be used on any suspension context.
yield(value: T)
is a function definition on the
SequenceScope
provided inside of
sequence { }
and
iterator { }
o

octylFractal

01/25/2020, 2:26 AM
*any coroutine suspension context. the suspend mechanism does not imply coroutines, e.g. you can't use
yield()
in
sequence {}
t

taer

01/27/2020, 3:21 PM
Thanks. We're using a buffered channel then creating flow's from that so we can have multiple flows with a single Kafka consumer(assuming bounds, etc)