ProgressScope

sealed interface ProgressScope : CoroutineScope

The receiver of an asyncWithProgress block: a CoroutineScope that can report progress and split the bar into slices.

Each ProgressScope owns a window, which is a part of the whole bar. The block's own scope owns the whole bar. A slice owns a part of its parent's window. A report of 0.5f in a slice fills half of that slice, not half of the bar.

The phase is the label of the current step. It is sticky: a report without a phase keeps the last phase.

You cannot implement this interface. Only asyncWithProgress creates it.

Threading

  • report is safe from any thread, for example from parallel workers.

  • Call slice and change the phase only from the block's own sequential code.

Watch out

  • Reports from parallel workers can arrive out of order, so the bar can move back a little. Count finished units in one shared counter and report it with report(done, total). For a bar that never moves back, filter at the collector.

  • After the operation completes, fails or is cancelled, reports do nothing.

Properties

Link copied to clipboard

Functions

Link copied to clipboard
fun <T> CoroutineScope.asyncWithProgress(context: CoroutineContext = EmptyCoroutineContext, start: CoroutineStart = CoroutineStart.DEFAULT, block: suspend ProgressScope.() -> T): ProgressFuture<T>

Starts a coroutine like async, and also publishes its progress as a StateFlow.

Link copied to clipboard
abstract fun report(fraction: Float?, phase: String? = null)

Reports how far this scope's window is done.

abstract fun report(done: Long, total: Long, phase: String? = null)

Reports done of total units, for example report(done = 3, total = 10) for 30%.

Link copied to clipboard
abstract fun slice(weight: Float, phase: String? = null): ProgressScope

Takes the next part of this window for one step and returns a scope for it.