```@Bean suspend fun myConvertedJavaConsumer = Con...
# server
a
Copy code
@Bean
suspend fun myConvertedJavaConsumer = Consumer<String> {
  mySuspendFunction(it)
}
The above code is giving me an error,
Suspension functions can be called only within coroutine body
. I am trying to convert a Java consumer to a Kotlin coroutine and I'm unsure how to proceed. This is using
spring-cloud-stream
and
spring-cloud-funciton-kotlin
libraries
r
You can't call a suspending function inside an implementation of java.util.function.Consumer as Consumer.accept isn't itself suspending
If you're using some library which you pass a Consumer as a callback which is called once, you can use
suspendCoroutine
If the consumer is to be called more than once, use
callbackFlow
Copy code
class Library {
        fun attachCallback(consumer: Consumer<String>) {
            consumer.accept("hey")
        }

        fun attachListener(consumer: Consumer<String>) {
            consumer.accept("hey")
            consumer.accept("hola")
        }
        
        fun removeListener(consumer: Consumer<String>) {
            TODO()
        }
    }

    fun thing() = runBlocking {
        lateinit var library: Library

        val result = suspendCoroutine { continuation ->
            library.attachCallback { continuation.resume(it) }
        }

        val results = callbackFlow { 
            val consumer: (t: String) -> Unit = { trySendBlocking(it) }
            library.attachListener(consumer)
            awaitClose { library.removeListener(consumer) }
        }.toList()
    }
a
I got it to compile by first translating it to a Kotlin lambda (supported by the
spring-cloud-function-kotlin
library) then wrapping it in a
coroutineScope.launch
. not sure if this is the best approach or not
r
it's fine if you are happy changing to the thread of the scope's dispatcher, else you could also do
Copy code
Consumer<String> {
  runBlocking {
    mySuspendFunction(it)
  }
}
which will block on the original thread
Looking at git (I've not used
spring-cloud-funciton-kotlin
) it looks like suspending functions may be natively supported. Perhaps try:
Copy code
@Bean
fun myConvertedJavaConsumer(): suspend (String) -> Unit {
  mySuspendFunction(it)
}
a
Thanks!!!