https://kotlinlang.org logo
#coroutines
Title
# coroutines
s

Sebastien Leclerc Lavallee

08/31/2020, 2:55 PM
Hi! I’m using AppAuth on Android to login to my backend and coroutines (ktor) on my transport layer to call APIs on that backend. I need to pass an access token to each of my calls. Using AppAuth I refresh this token with the
AuthState.performActionWithFreshTokens(callback: (freshToken: String?))
which uses a callback to give me the fresh token. And my transport service uses coroutines, something like:
Copy code
class TransportService {
  suspend fun getAllTasks(): List<Task> {
    authState.performActionWithFreshToken() { freshToken ->
      return ktorClient.get<List<Task>>()
    }
  }
}
Now, I have an error where I use the ktor client:
suspend function can be called only within coroutines scope
. That is because the callback function is not a coroutine scope. If I create a new scope within the callback, will this work well with the main function? What can I do to keep my transport with suspend function and not use completion handler everywhere? Thanks 🙂
s

streetsofboston

08/31/2020, 2:59 PM
Copy code
suspend fun getAllTasks(): List<Task> = suspendCancellableCoroutine { cont ->
    authState.performActionWithFreshToken() { freshToken ->
      cont.resume(ktorClient.get<List<Task>>())
    }
  }
(the key here is the call to
suspendCancellableCoroutine
)
s

Sebastien Leclerc Lavallee

08/31/2020, 3:59 PM
Thanks ! I don’t see any resume function on
cont
which take a closure to execute more suspend function, something like :
Copy code
suspend fun getAllTasks(): List<Task> = suspendCancellableCoroutine { cont ->
    authState.performActionWithFreshToken() { freshToken ->
      cont.resume() {
        var list = listOf<Task>()

        do {
          list.addAll(ktorClient.get<List<Task>>())
        }
        while(moreTask)

        return list
      }
    }
  }
It’s possible with
suspendCancellableCoroutine
? Thanks
s

streetsofboston

08/31/2020, 4:06 PM
Copy code
suspend fun getAllTasks(): List<Task> = suspendCancellableCoroutine { cont ->
    authState.performActionWithFreshToken() { freshToken ->
        var list = listOf<Task>()

        do {
          list.addAll(ktorClient.get<List<Task>>())
        }
        while(moreTask)

        cont.resume(list)
      }
  }
s

Sebastien Leclerc Lavallee

08/31/2020, 4:08 PM
But this
ktorClient.get<List<Task>>()
is a suspend function and when called it’s not in the coroutine scope anymore because of the callback 🤔 I have the same error
Maybe inside the callback I can create a new coroutine scope and call the
cont.resume()
when I’m finished
2 Views