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

groostav

09/14/2020, 8:59 PM
So I've got a bad idea: What if we embedded a progress bar control and a delegating
CoroutineDispatcher
into a coroutineContext such that we could ~automagically make progress bars based on the number of suspension points? I think this is akin to reflecting on the number of states the coroutine state machine has. Of course, while-loops and if-statements blow this up, but still I feel like there might be something here. Has anybody got an implementation doing something like this?
I'm tired of replacing my buggy java-based progress-bar implementing spagetti code with kotlin coroutine backed code that is way more readable but only renders a spinner
e

ephemient

09/15/2020, 3:08 AM
interesting thought but I have no idea how you would count the number of suspension points left to go
g

gildor

09/15/2020, 3:38 AM
I don’t think it’s possible to do on level of coroutine dispatcher
Also I don’t think that it good enough to just count suspend points
g

groostav

09/15/2020, 6:32 AM
@gildor no but its a start, to make it work youd need some pretty heavy static code analysis
you could do something like
Copy code
fun launchProgressBarableTask(subtaskCount: Int, job: suspend () -> R): Deferred<R> { ... }

suspend fun enterSubtask(subtask: suspend () -> R): R { ... }
usage:
Copy code
fun onUIEvent(){
  launchProgressBarableTask(subtaskCount = customers.size){
    for(customer in customers){
      results += enterSubtask {
        lookupCustomerDetailsFromSlowDB(customer)
      }

      publish(results)
    }
  }
}
you dont actually need
enterSubtask
since you can infer it from the dispatch but that seems really brittle to me
of course this also is just working with 1 level of the job tree
if we knew more about ther size of the job tree ahead of time we could build really high fidelity progress bars
g

gildor

09/15/2020, 7:18 AM
wouldn’t be easier publish result explicitly?
I see your point, just curious is effort really worth it, maybe report progress explicitly is easier to maintain and it provides better progress reporting
It also may be pretty idiomatic with right dsl (because you alredy have launchProgressBarableTask which may provice custom scope in lambda):
Copy code
fun onUIEvent(){
  launchProgressBarableTask(subtaskCount = customers.size){
    return mapWithProgress(customers) { customer ->
      enterSubtask {
        lookupCustomerDetailsFromSlowDB(customer)
      }
    }
  }
}
where
mapWithProgress
is a method of
launchProgressBarableTask
which reports progress for each item of
customers
and report it to
launchProgressBarableTask
2 Views