Skip to content

//workflow/com.squareup.workflow1/Worker

Worker

[jvm] interface WorkerOutputT>

Represents a unit of asynchronous work that can have zero, one, or multiple outputs.

Workers allow you to execute arbitrary, possibly asynchronous tasks in a declarative manner. To perform their tasks, workers return a Flow. Workers are effectively Flows that can be compared to determine equivalence between render passes. A Workflow uses Workers to perform asynchronous work during the render pass by calling BaseRenderContext.runningWorker.

See the documentation on run for more information on the returned Flow is consumed and how to implement asynchronous work.

See the documentation on doesSameWorkAs for more details on how and when workers are compared and the worker lifecycle.

Example: Network request

Let’s say you have a network service with an API that returns a number, and you want to call that service from a Workflow.

interface TimeService {
suspend fun getTime(timezone: String): Long
}

The first step is to define a Worker that can call this service, and maybe an extension function on your service class:

fun TimeService.getTimeWorker(timezone: String): Worker = TimeWorker(timezone, this)

private class TimeWorker(
val timezone: String,
val service: TimeService
): Worker {

override fun run(): Flow = flow {
val time = service.getTime(timezone)
emit(time)
}
}

You also need to define how to determine if a previous Worker is already doing the same work. This will ensure that if the same request is made by the same Workflow in adjacent render passes, we’ll keep the request alive from the first pass.

override fun doesSameWorkAs(otherWorker: Worker<*>): Boolean =
otherWorker is TimeWorker &&
timezone == otherWorker.timezone

Now you can request the time from your Workflow:

class MyWorkflow(private val timeWorker: TimeWorker) {
override fun render(…): Foo {
context.runningWorker(timeWorker) { time -> emitOutput(“The time is $time”) }
}

Alternatively, if the response is a unique type, unlikely to be shared by any other workers, you don’t even need to create your own Worker class, you can use a builder, and the worker will automatically be distinguished by that response type:

interface TimeService {
fun getTime(timezone: String): Deferred
}

fun TimeService.getTimeWorker(timezone: String): Worker =
Worker.from { getTime(timezone).await()) }

See also

jvm

com.squareup.workflow1.Worker.Companion

Types

Name Summary
Companion [jvm]
Content
object Companion


Functions

Name Summary
doesSameWorkAs [jvm]
Content
open fun doesSameWorkAs(otherWorker: Worker<*>): Boolean
More info
Override this method to define equivalence between Workers.


run [jvm]
Content
abstract fun run(): Flow<OutputT>
More info
Returns a Flow to execute the work represented by this worker.


Inheritors

Name
LifecycleWorker
PublisherWorker
WorkerSink

Extensions

Name Summary
test [jvm]
Content
fun <T> Worker<T>.test(timeoutMs: Long = DEFAULT_TIMEOUT_MS, block: suspend WorkerTester<T>.() -> Unit)
More info
Test a Worker by defining assertions on its output within block.


transform [jvm]
Content
fun <T, R> Worker<T>.transform(transform: (Flow<T>) -> Flow<R>): Worker<R>
More info
Returns a Worker that transforms this Worker‘s Flow by calling transform.