Skip to content

Commit 3ae6053

Browse files
Create a WorkflowSession type to pass to launchWorkflowIn's block instead of individual parameters.
1 parent 6013cb2 commit 3ae6053

File tree

6 files changed

+94
-45
lines changed

6 files changed

+94
-45
lines changed

kotlin/samples/hello-terminal/terminal-workflow/src/main/java/com/squareup/sample/helloterminal/terminalworkflow/TerminalWorkflowRunner.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,8 @@ private suspend fun runTerminalWorkflow(
107107
// Use the result as the parent Job of the runtime coroutine so it gets cancelled automatically
108108
// if there's an error.
109109
val result =
110-
launchWorkflowIn(this, workflow, inputs.asFlow()) { renderingsAndSnapshots, outputs ->
111-
val renderings = renderingsAndSnapshots.map { it.rendering }
110+
launchWorkflowIn(this, workflow, inputs.asFlow()) { session ->
111+
val renderings = session.renderingsAndSnapshots.map { it.rendering }
112112
.produceIn(this)
113113

114114
launch {
@@ -149,7 +149,7 @@ private suspend fun runTerminalWorkflow(
149149
}
150150
}
151151

152-
return@launchWorkflowIn async { outputs.first() }
152+
return@launchWorkflowIn async { session.outputs.first() }
153153
}
154154

155155
val exitCode = result.await()

kotlin/workflow-runtime/src/main/java/com/squareup/workflow/LaunchWorkflow.kt

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,7 @@ import org.jetbrains.annotations.TestOnly
3737
*/
3838
@UseExperimental(ExperimentalCoroutinesApi::class)
3939
internal typealias Configurator <O, R, T> = CoroutineScope.(
40-
renderingsAndSnapshots: Flow<RenderingAndSnapshot<R>>,
41-
outputs: Flow<O>
40+
session: WorkflowSession<O, R>
4241
) -> T
4342

4443
/**
@@ -102,10 +101,7 @@ fun <PropsT, OutputT : Any, RenderingT, RunnerT> launchWorkflowIn(
102101
workflow: Workflow<PropsT, OutputT, RenderingT>,
103102
props: Flow<PropsT>,
104103
initialSnapshot: Snapshot? = null,
105-
beforeStart: CoroutineScope.(
106-
renderingsAndSnapshots: Flow<RenderingAndSnapshot<RenderingT>>,
107-
outputs: Flow<OutputT>
108-
) -> RunnerT
104+
beforeStart: CoroutineScope.(session: WorkflowSession<OutputT, RenderingT>) -> RunnerT
109105
): RunnerT = launchWorkflowImpl(
110106
scope,
111107
RealWorkflowLoop,
@@ -132,10 +128,7 @@ fun <PropsT, StateT, OutputT : Any, RenderingT, RunnerT> launchWorkflowForTestFr
132128
workflow: StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>,
133129
props: Flow<PropsT>,
134130
initialState: StateT,
135-
beforeStart: CoroutineScope.(
136-
renderingsAndSnapshots: Flow<RenderingAndSnapshot<RenderingT>>,
137-
outputs: Flow<OutputT>
138-
) -> RunnerT
131+
beforeStart: CoroutineScope.(session: WorkflowSession<OutputT, RenderingT>) -> RunnerT
139132
): RunnerT = launchWorkflowImpl(
140133
scope,
141134
RealWorkflowLoop,
@@ -161,7 +154,8 @@ internal fun <PropsT, StateT, OutputT : Any, RenderingT, RunnerT> launchWorkflow
161154
val workflowScope = scope + Job(parent = scope.coroutineContext[Job])
162155

163156
// Give the caller a chance to start collecting outputs.
164-
val result = beforeStart(workflowScope, renderingsAndSnapshots.asFlow(), outputs.asFlow())
157+
val session = WorkflowSession(renderingsAndSnapshots.asFlow(), outputs.asFlow())
158+
val result = beforeStart(workflowScope, session)
165159

166160
val workflowJob = workflowScope.launch {
167161
// Run the workflow processing loop forever, or until it fails or is cancelled.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright 2019 Square Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.squareup.workflow
17+
18+
import kotlinx.coroutines.flow.Flow
19+
20+
/**
21+
* A tuple of [Flow]s representing all the emissions from the workflow runtime.
22+
*
23+
* Passed to the function taken by [launchWorkflowIn].
24+
*/
25+
class WorkflowSession<out OutputT : Any, out RenderingT>(
26+
val renderingsAndSnapshots: Flow<RenderingAndSnapshot<RenderingT>>,
27+
val outputs: Flow<OutputT>
28+
)

kotlin/workflow-runtime/src/test/java/com/squareup/workflow/internal/LaunchWorkflowTest.kt

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class LaunchWorkflowTest {
8080
emptyFlow(),
8181
initialSnapshot = null,
8282
initialState = null
83-
) { renderings, _ -> renderings }
83+
) { it.renderingsAndSnapshots }
8484

8585
assertTrue(rendered)
8686
runBlocking {
@@ -103,7 +103,7 @@ class LaunchWorkflowTest {
103103
emptyFlow(),
104104
initialSnapshot = null,
105105
initialState = null
106-
) { _, outputs -> outputs }
106+
) { it.outputs }
107107

108108
assertTrue(rendered)
109109
runBlocking {
@@ -129,7 +129,7 @@ class LaunchWorkflowTest {
129129
emptyFlow(),
130130
initialSnapshot = null,
131131
initialState = null
132-
) { renderings, _ -> renderings }
132+
) { it.renderingsAndSnapshots }
133133

134134
runBlocking {
135135
assertEquals("foo", renderings.first().rendering)
@@ -150,10 +150,10 @@ class LaunchWorkflowTest {
150150
emptyFlow(),
151151
initialSnapshot = null,
152152
initialState = null
153-
) { _, outputs ->
153+
) { session ->
154154
Pair(
155-
outputs.produceIn(this),
156-
outputs.produceIn(this)
155+
session.outputs.produceIn(this),
156+
session.outputs.produceIn(this)
157157
)
158158
}
159159

@@ -181,7 +181,7 @@ class LaunchWorkflowTest {
181181
emptyFlow(),
182182
initialSnapshot = null,
183183
initialState = null
184-
) { renderings, _ -> renderings }
184+
) { it.renderingsAndSnapshots }
185185

186186
runBlocking {
187187
assertEquals("six", renderings.first().rendering)
@@ -202,7 +202,7 @@ class LaunchWorkflowTest {
202202
emptyFlow(),
203203
initialSnapshot = null,
204204
initialState = null
205-
) { _, outputs -> outputs }
205+
) { it.outputs }
206206

207207
runBlocking {
208208
val outputsChannel = outputs.produceIn(this)
@@ -235,13 +235,13 @@ class LaunchWorkflowTest {
235235
emptyFlow(),
236236
initialSnapshot = null,
237237
initialState = null
238-
) { _, outputs ->
238+
) { session ->
239239
// Disable buffering for this subscription channel.
240240
// There will still be some buffering:
241241
// - BroadcastChannel buffer has the minimum buffer size of 1.
242242
// - Implicit buffer from the asFlow coroutine.
243243
// - Implicit buffer from the coroutine created by produceIn.
244-
outputs.buffer(0)
244+
session.outputs.buffer(0)
245245
.produceIn(this)
246246
.also { assertNull(it.poll()) }
247247
}
@@ -270,7 +270,7 @@ class LaunchWorkflowTest {
270270
emptyFlow(),
271271
initialSnapshot = null,
272272
initialState = null
273-
) { renderings, outputs -> Pair(renderings, outputs) }
273+
) { Pair(it.renderingsAndSnapshots, it.outputs) }
274274

275275
runBlocking {
276276
assertTrue(renderings.toList().isEmpty())
@@ -290,11 +290,14 @@ class LaunchWorkflowTest {
290290
emptyFlow(),
291291
initialSnapshot = null,
292292
initialState = null
293-
) { r, o ->
293+
) { session ->
294294
coroutineContext[Job]!!.invokeOnCompletion {
295295
cancelled = true
296296
}
297-
Pair(r.produceIn(this), o.produceIn(this))
297+
Pair(
298+
session.renderingsAndSnapshots.produceIn(this),
299+
session.outputs.produceIn(this)
300+
)
298301
}
299302

300303
assertFalse(cancelled)
@@ -319,8 +322,12 @@ class LaunchWorkflowTest {
319322
emptyFlow(),
320323
initialSnapshot = null,
321324
initialState = null
322-
) { r, o ->
323-
Triple(coroutineContext[Job]!!, r.produceIn(this), o.produceIn(this))
325+
) { session ->
326+
Triple(
327+
coroutineContext[Job]!!,
328+
session.renderingsAndSnapshots.produceIn(this),
329+
session.outputs.produceIn(this)
330+
)
324331
}
325332

326333
assertTrue(parentJob.children.count() > 0)
@@ -344,7 +351,13 @@ class LaunchWorkflowTest {
344351
emptyFlow(),
345352
initialSnapshot = null,
346353
initialState = null
347-
) { r, o -> Triple(coroutineContext[Job]!!, r.produceIn(this), o.produceIn(this)) }
354+
) { session ->
355+
Triple(
356+
coroutineContext[Job]!!,
357+
session.renderingsAndSnapshots.produceIn(this),
358+
session.outputs.produceIn(this)
359+
)
360+
}
348361

349362
assertTrue(job.isCancelled)
350363
assertTrue(renderings.isClosedForReceive)
@@ -368,12 +381,16 @@ class LaunchWorkflowTest {
368381
emptyFlow(),
369382
initialSnapshot = null,
370383
initialState = null
371-
) { renderings, outputs ->
384+
) { session ->
372385
launch {
373386
trigger.await()
374-
renderings.collect { throw ExpectedException() }
387+
session.renderingsAndSnapshots.collect { throw ExpectedException() }
375388
}
376-
Triple(coroutineContext[Job]!!, renderings.produceIn(this), outputs.produceIn(this))
389+
Triple(
390+
coroutineContext[Job]!!,
391+
session.renderingsAndSnapshots.produceIn(this),
392+
session.outputs.produceIn(this)
393+
)
377394
}
378395

379396
assertTrue(job.isActive)
@@ -411,12 +428,16 @@ class LaunchWorkflowTest {
411428
emptyFlow(),
412429
initialSnapshot = null,
413430
initialState = null
414-
) { renderings, outputs ->
431+
) { session ->
415432
launch {
416433
trigger.await()
417-
outputs.collect { throw ExpectedException() }
434+
session.outputs.collect { throw ExpectedException() }
418435
}
419-
Triple(coroutineContext[Job]!!, renderings.produceIn(this), outputs.produceIn(this))
436+
Triple(
437+
coroutineContext[Job]!!,
438+
session.renderingsAndSnapshots.produceIn(this),
439+
session.outputs.produceIn(this)
440+
)
420441
}
421442

422443
assertTrue(job.isActive)
@@ -446,7 +467,7 @@ class LaunchWorkflowTest {
446467
emptyFlow(),
447468
initialSnapshot = null,
448469
initialState = null
449-
) { _, _ ->
470+
) { _ ->
450471
throw ExpectedException()
451472
}
452473
}
@@ -468,8 +489,12 @@ class LaunchWorkflowTest {
468489
emptyFlow(),
469490
initialSnapshot = null,
470491
initialState = null
471-
) { r, o ->
472-
Triple(coroutineContext[Job]!!, r.produceIn(this), o.produceIn(this))
492+
) { session ->
493+
Triple(
494+
coroutineContext[Job]!!,
495+
session.renderingsAndSnapshots.produceIn(this),
496+
session.outputs.produceIn(this)
497+
)
473498
}
474499

475500
assertTrue(job.isCancelled)

kotlin/workflow-testing/src/main/java/com/squareup/workflow/testing/WorkflowTester.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,8 @@ fun <T, PropsT, OutputT : Any, RenderingT>
232232
this@testFromStart,
233233
inputs.asFlow(),
234234
snapshot
235-
) { renderings, outputs ->
236-
WorkflowTester(this, inputs, renderings, outputs)
235+
) { session ->
236+
WorkflowTester(this, inputs, session.renderingsAndSnapshots, session.outputs)
237237
.apply { collectFromWorkflow() }
238238
}
239239

@@ -278,8 +278,8 @@ fun <T, PropsT, StateT, OutputT : Any, RenderingT>
278278
this@testFromState,
279279
inputs.asFlow(),
280280
initialState
281-
) { renderings, outputs ->
282-
WorkflowTester(this, inputs, renderings, outputs)
281+
) { session ->
282+
WorkflowTester(this, inputs, session.renderingsAndSnapshots, session.outputs)
283283
.apply { collectFromWorkflow() }
284284
}
285285

kotlin/workflow-ui-android/src/main/java/com/squareup/workflow/ui/WorkflowRunnerViewModel.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,11 @@ internal class WorkflowRunnerViewModel<OutputT : Any>(
5555
return with(configure()) {
5656
launchWorkflowIn(
5757
CoroutineScope(dispatcher), workflow, props, snapshot
58-
) { renderings, output ->
58+
) { session ->
5959
@Suppress("UNCHECKED_CAST")
60-
WorkflowRunnerViewModel(this, renderings, output, viewRegistry) as T
60+
WorkflowRunnerViewModel(
61+
this, session.renderingsAndSnapshots, session.outputs, viewRegistry
62+
) as T
6163
}
6264
}
6365
}

0 commit comments

Comments
 (0)