Skip to content

Commit 4345d22

Browse files
Merge pull request #1250 from square/sedwards/cache-it-all
1249: Cache Intercepted Workflow Instance
2 parents 12c6fc4 + 2e43d2c commit 4345d22

File tree

1 file changed

+25
-10
lines changed
  • workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal

1 file changed

+25
-10
lines changed

workflow-runtime/src/commonMain/kotlin/com/squareup/workflow1/internal/WorkflowNode.kt

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
7171
override val identifier: WorkflowIdentifier get() = id.identifier
7272
override val renderKey: String get() = id.name
7373
override val sessionId: Long = idCounter.createId()
74+
private var cachedWorkflowInstance: StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>
75+
private var interceptedWorkflowInstance: StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>
7476

7577
private val subtreeManager = SubtreeManager(
7678
snapshotCache = snapshot?.childTreeSnapshots,
@@ -99,8 +101,9 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
99101
init {
100102
interceptor.onSessionStarted(this, this)
101103

102-
state = interceptor.intercept(workflow, this)
103-
.initialState(initialProps, snapshot?.workflowSnapshot, this)
104+
cachedWorkflowInstance = workflow
105+
interceptedWorkflowInstance = interceptor.intercept(cachedWorkflowInstance, this)
106+
state = interceptedWorkflowInstance.initialState(initialProps, snapshot?.workflowSnapshot, this)
104107
}
105108

106109
override fun toString(): String {
@@ -132,10 +135,10 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
132135
fun snapshot(workflow: StatefulWorkflow<*, *, *, *>): TreeSnapshot {
133136
@Suppress("UNCHECKED_CAST")
134137
val typedWorkflow = workflow as StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>
138+
updateCachedWorkflowInstance(typedWorkflow)
135139
return interceptor.onSnapshotStateWithChildren({
136140
val childSnapshots = subtreeManager.createChildSnapshots()
137-
val rootSnapshot = interceptor.intercept(typedWorkflow, this)
138-
.snapshotState(state)
141+
val rootSnapshot = interceptedWorkflowInstance.snapshotState(state)
139142
TreeSnapshot(
140143
workflowSnapshot = rootSnapshot,
141144
// Create the snapshots eagerly since subtreeManager is mutable.
@@ -202,6 +205,20 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
202205
coroutineContext.cancel(cause)
203206
}
204207

208+
/**
209+
* Call this after we have been passed any workflow instance, in [render] or [snapshot]. It may
210+
* have changed and we should check to see if we need to update our cached instances.
211+
*/
212+
private fun updateCachedWorkflowInstance(
213+
workflow: StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>
214+
) {
215+
if (workflow !== cachedWorkflowInstance) {
216+
// The instance has changed.
217+
cachedWorkflowInstance = workflow
218+
interceptedWorkflowInstance = interceptor.intercept(cachedWorkflowInstance, this)
219+
}
220+
}
221+
205222
/**
206223
* Contains the actual logic for [render], after we've casted the passed-in [Workflow]'s
207224
* state type to our `StateT`.
@@ -210,11 +227,11 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
210227
workflow: StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>,
211228
props: PropsT
212229
): RenderingT {
213-
updatePropsAndState(workflow, props)
230+
updateCachedWorkflowInstance(workflow)
231+
updatePropsAndState(props)
214232

215233
baseRenderContext.unfreeze()
216-
val rendering = interceptor.intercept(workflow, this)
217-
.render(props, state, context)
234+
val rendering = interceptedWorkflowInstance.render(props, state, context)
218235
baseRenderContext.freeze()
219236

220237
workflowTracer.trace("UpdateRuntimeTree") {
@@ -230,12 +247,10 @@ internal class WorkflowNode<PropsT, StateT, OutputT, RenderingT>(
230247
}
231248

232249
private fun updatePropsAndState(
233-
workflow: StatefulWorkflow<PropsT, StateT, OutputT, RenderingT>,
234250
newProps: PropsT
235251
) {
236252
if (newProps != lastProps) {
237-
val newState = interceptor.intercept(workflow, this)
238-
.onPropsChanged(lastProps, newProps, state)
253+
val newState = interceptedWorkflowInstance.onPropsChanged(lastProps, newProps, state)
239254
state = newState
240255
}
241256
lastProps = newProps

0 commit comments

Comments
 (0)