I'm using the HiveMQ Android Client in my Android App. I "probe" for a device using a transient object for the transaction, which wraps an Mqtt3AsyncClient.
fun probe(callback: ((String) -> Unit)) { ... client .connectWith() .cleanSession(true) .keepAlive(60) .simpleAuth()...applySimpleAuth().send() .whenComplete { _, _ -> client .subscribeWith() .addSubscription().topicFilter(eventTopic).applySubscription() .callback { message -> handleMessage(message.topic, message.payloadAsBytes)) } .send() .whenComplete { _, _ -> attemptToCommunicate()} } } The problem is that my handleMessage function (which will run async because that's what the async client is all about) makes a call to a suspend fun in it's body, e.g.
fun handleMessage(topic:String, message:Bytes) { ... saveDataFuncThatIsDefinedWithSuspend(...) ... } I can't exactly mark handleMessage as suspend, because it's call from the callback will be an error. Marking the probe function as suspend doesn't solve that either. And I'm not at liberty to not use the HiveMQ client, so I'm stuck with the callback.
I toyed with wrapping the suspend function as such:
CoroutineScope(Dispatchers.IO).launch { saveDataFuncThatIsDefinedWithSuspend(...) } but I got the impression, that this is considered a bad idea? Or I could wrap a runBlocking around it, but again, that seems frowned upon. Should I make my transient transaction object itself a CoroutineScope implementor? I'm struggling with how one bridges these two worlds in a case like this.