How to struture coroutine code without suspend function

59 views Asked by At

I have a method called saveAccount

fun saveAccount(id: Int, newName: String): Account {
    val encryptedNames: List<String> = repository.findNamesById(id)
    val decryptedNames: List<String> = encryptedNames.map { cryptographyService.decrypt(it) }

    if(decryptedNames.contains(newName))
        throw IllegalStateException()

    return repository.save(newName)
}

I want to concurrently decrypt all names, so I did:

suspend fun saveAccount(id: Int, newName: String): Account {
    val encryptedNames: List<String> = repository.findNamesById(id)

    val decryptedNames: List<String> = encryptedNames.map { 
        CoroutineScope(Dispatchers.IO).async {
            cryptographyService.decrypt(it) 
        } 
    }.awaitAll()

    if(decryptedNames.contains(newName))
        throw IllegalStateException()

    return repository.save(newName)
}

Until now everything is fine, but the question is: I can't make saveAccount a suspend function. What should I do?

1

There are 1 answers

0
Willi Mentzel On BEST ANSWER

So, you want to decrypt each name in a separate coroutine, but saveAccount should only return when all decryption is done.

You can use runBlocking for that:

fun saveAccount(id: Int, newName: String): Account {
    // ...
    val decryptedNames = runBlocking {
        encryptedNames.map {
            CoroutineScope(Dispatchers.IO).async {
                cryptographyService.decrypt(it) 
            }
        }.awaitAll()
    }
    // ...
}

This way saveAccount does not have to be a suspend function.