I could use some advice on making an API feel kotlin-native.

I’ve got a Java API that basically looks like this:

public class Client { void sendData(String message, Callback callback); // Enqueues data to send. void flush(); // Actually sends the data. public interface Callback { // Callback used once data has been sent. void onSuccess(int responseCode); void onFailure(Throwable error); } } 

The callback thing is a huge pain (this is an over-simplification), and this will be used from Kotlin code, so I want to wrap it, but make it feel as native as I possible can. If I was working in Javascript I’d want my client library to look like this:

async function foo() { let clientWrapper = new ClientWrapper(); let a = clientWrapper.send("Hello"); let b = clientWrapper.send("World"); clientWrapper.flush(); let aResponse = await a; let bResponse = await b; return aResponse == 200 && bResponse = 200; } 

My first attempt looked something like this:

class ClientWrapper { private val client = Client() suspend fun send(message: String) = suspendCoroutine { cont -> client.sendMessage(message, object : Callback { override fun onSuccess(responseCode: Int) { cont.resumeWith(responseCode) } override fun onFailure(error: Throwable) { cont.resumeWithException(error) } }) } } fun foo() { runBlocking { val clientWrapper = ClientWrapper() val aResponse = clientWrapper.send("Hello") val bResponse = clientWrapper.send("World") clientWrapper.flush() } } 

This didn’t work very well. runBlocking did what it says on the tin, and blocked on both send() calls. Instead I want to be able to continue from send immediately, run flush() and then block until I have both aResponse and bResponse.

Is there a clean way to do this in Kotlin?

submitted by /u/Shaftway
[link] [comments]