diff --git a/formula/src/main/java/com/instacart/formula/FormulaRuntime.kt b/formula/src/main/java/com/instacart/formula/FormulaRuntime.kt index 294368fa..5280e364 100644 --- a/formula/src/main/java/com/instacart/formula/FormulaRuntime.kt +++ b/formula/src/main/java/com/instacart/formula/FormulaRuntime.kt @@ -89,41 +89,42 @@ class FormulaRuntime( if (isEvaluating) return try { - val freshRun = !isExecuting - if (freshRun) { - inspector?.onRunStarted(shouldEvaluate) - } + runFormula(shouldEvaluate) + emitOutputIfNeeded() + } catch (e: Throwable) { + isEvaluating = false - val manager = checkNotNull(manager) - val currentInput = checkNotNull(input) + manager?.markAsTerminated() + onError(e) + manager?.performTerminationSideEffects() + } + } - isEvaluating = true - if (shouldEvaluate && !manager.terminated) { - evaluationPhase(manager, currentInput) - } - isEvaluating = false + private fun runFormula(evaluate: Boolean) { + val freshRun = !isExecuting + if (freshRun) { + inspector?.onRunStarted(evaluate) + } - if (shouldEvaluate || effectQueue.isNotEmpty()) { - executionRequested = true - } - if (isExecuting) return + val manager = checkNotNull(manager) + val currentInput = checkNotNull(input) + + isEvaluating = true + if (evaluate && !manager.terminated) { + evaluationPhase(manager, currentInput) + } + isEvaluating = false - effectPhase(manager) + if (evaluate || effectQueue.isNotEmpty()) { + executionRequested = true + } - if (freshRun) { - inspector?.onRunFinished() - } + if (isExecuting) return - if (hasInitialFinished && emitOutput) { - emitOutput = false - onOutput(checkNotNull(lastOutput)) - } - } catch (e: Throwable) { - isEvaluating = false + effectPhase(manager) - manager?.markAsTerminated() - onError(e) - manager?.performTerminationSideEffects() + if (freshRun) { + inspector?.onRunFinished() } } @@ -157,9 +158,8 @@ class FormulaRuntime( while (executionRequested) { executionRequested = false - val transitionId = manager.transitionID // We execute pending side-effects even after termination - if (executeEffects(manager, transitionId)) { + if (executeEffects(manager)) { continue } } @@ -169,7 +169,9 @@ class FormulaRuntime( /** * Executes effects from the [effectQueue]. */ - private fun executeEffects(manager: FormulaManagerImpl<*, *, *>, transitionId: Long): Boolean { + private fun executeEffects(manager: FormulaManagerImpl<*, *, *>): Boolean { + isExecuting = true + val transitionId = manager.transitionID while (effectQueue.isNotEmpty()) { val effects = effectQueue.pollFirst() if (effects != null) { @@ -183,4 +185,11 @@ class FormulaRuntime( } return false } + + private fun emitOutputIfNeeded() { + if (hasInitialFinished && emitOutput) { + emitOutput = false + onOutput(checkNotNull(lastOutput)) + } + } }