I have a suspend function from which I want to return the result of a Java 5 Future. The future object comes from another library Firebase Cloud Firestore- Admin SDK for Java and provides a blocking call get() to retrieve the result of the said future.
My function looks like this-
suspend fun getPrefix(messageCreateEvent: MessageCreateEvent): String {
val snapshot = db.collection("prefixes")
.document(messageCreateEvent.guildId.get().asString())
.get() //This returns a future
.get() //Retrieves the future's result (Blocks thread; IDE gives warning)
//Return the prefix
return if (snapshot.exists())
snapshot.getString("prefix") ?: DEFAULT_PREFIX
else DEFAULT_PREFIX
}
Solutions I have considered
The first thing that I considered was to look in kotlinx.coroutine for extensions to bridge the futures. While the extensions exist, they do only for CompletionStatge. So I decided to wrap the future into one ()-
val snapshot = CompleteableFuture.supplyAsync {
db.collection("prefixes")
.document(messageCreateEvent.guildId.get().asString())
.get() // This returns a future
.get() // Get the result
}.await()
I am quite inexperienced and not sure if this is was proper solution. I queried my question on a programming community, where a person recommended me to use a Deferred-
val deferred = CompletableDeferred<DocumentSnapshot>()
val future = db.collection("prefixes")
.document(messageCreateEvent.guildId.get().asString())
.get()
future.addListener(
Runnable { deferred.complete(future.get()) },
ForkJoinPool.commonPool()
)
val snapshot = deferred.await()
I've give it quite a time to search for a way to bridge futures to co-routines, there isn't even a similar question on SO. Through, I wouldn't be surprised if this question gets a duplicate mark.