Storing the result from the other operations

Currently, we aren't storing the result of the other suspending functions. To do so, we need to create a more complete implementation of the state machine, which can be easy if we use CoroutineImpl as the base. In this case, we could create this private class outside of the function:

private class GetUserSummarySM: CoroutineImpl {

var value: Any? = null
var exception: Throwable? =
null
var cont: Continuation<Any?>? = null
val id: Int? = null
var profile: Profile? = null
var age: Int? = null
var terms: Terms? = null

override fun doResume(data: Any?, exception: Throwable?) {
this.value = data
this.exception = exception
getUserSummary(id, this)
}
}

Here we have done the following:

  • Mapped all the different variables that exist in the function to the class (id, profile, age, terms)
  • Added one value to store the data returned by the caller in doResume()
  • Added one value to store the exception that can be sent in doResume() 
  • Added one value to store the initial continuation that is sent when the execution of getUserSummary() is first started

So now we can update the function itself to both use this class and to set the properties as they become available:

val sm = cont as? GetUserSummarySM ?: GetUserSummarySM()

when(sm.label) {
0 -> { // Label 0 -> first execution
sm.cont = cont
logger.log("fetching summary of $id")
sm.label = 1
fetchProfile(id, sm)
return
}
1 -> { // label 1 -> resuming
sm.profile = sm.value as Profile
sm.age = calculateAge(sm.profile!!.dateOfBirth)
sm.label = 2
validateTerms(sm.profile!!.country, sm.age!!, sm)
return
}
2 -> {// label 2 -> resuming and terminating
sm.terms = sm.value as Terms
UserSummary(sm.profile!!, sm.age!!, sm.terms!!)
}
}

There are many important things in this code:

  • We check whether cont is an instance of GetUserSummarySM; if that's the case, we use it as the state. If not, that means that it's the initial execution of the function, so a new one is created.
  • As part of the first label, we store the current cont in the state machine. This will be used later to resume the caller of getUserSummary().
  • The second and third labels start by casting sm.value into the result of the last operation and storing it in the correct variable of the state machine.
  • We use all the variables directly from the state machine.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.195.111