Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit85eea0d

Browse files
Merge pull request#1434 from square/sedwards/update-for-dropped
Add Runtime Update Lines for Dropped Actions
2 parents886e65b +7f4eb91 commit85eea0d

File tree

4 files changed

+224
-1
lines changed

4 files changed

+224
-1
lines changed

‎workflow-tracing/api/workflow-tracing.api‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ public final class com/squareup/workflow1/tracing/ActionAppliedLogLine$WorkflowA
2020
public static fun values ()[Lcom/squareup/workflow1/tracing/ActionAppliedLogLine$WorkflowActionLogType;
2121
}
2222

23+
public final class com/squareup/workflow1/tracing/ActionDroppedLogLine : com/squareup/workflow1/tracing/RuntimeUpdateLogLine {
24+
public fun <init> (Ljava/lang/String;)V
25+
public final fun getActionName ()Ljava/lang/String;
26+
public fun log (Ljava/lang/StringBuilder;)V
27+
}
28+
2329
public final class com/squareup/workflow1/tracing/ChainedWorkflowRuntimeTracerKt {
2430
public static final fun wrap (Lcom/squareup/workflow1/WorkflowInterceptor$RenderContextInterceptor;Lcom/squareup/workflow1/WorkflowInterceptor$RenderContextInterceptor;)Lcom/squareup/workflow1/WorkflowInterceptor$RenderContextInterceptor;
2531
}

‎workflow-tracing/src/main/java/com/squareup/workflow1/tracing/RuntimeUpdateLogLine.kt‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,18 @@ public data object SkipLogLine : RuntimeUpdateLogLine {
5858
}
5959
}
6060

61+
/**
62+
* An action that was queued but got dropped because the Workflow session ended.
63+
*/
64+
publicclassActionDroppedLogLine(
65+
valactionName:String,
66+
) : RuntimeUpdateLogLine {
67+
overridefunlog(builder:StringBuilder) {
68+
builder.append("DROPPED:$actionName")
69+
.append('\n')
70+
}
71+
}
72+
6173
/**
6274
* The Workflow runtime has applied an action.
6375
*/

‎workflow-tracing/src/main/java/com/squareup/workflow1/tracing/WorkflowRuntimeMonitor.kt‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ public class WorkflowRuntimeMonitor(
9191
droppedActions:List<WorkflowAction<P,S,O>>,
9292
session:WorkflowSession
9393
) {
94+
droppedActions.forEach { droppedAction->
95+
runtimeUpdates.logUpdate(
96+
updateLine=ActionDroppedLogLine(
97+
actionName= droppedAction.toLoggingShortName()
98+
)
99+
)
100+
}
94101
onWorkflowStopped(session.sessionId)
95102
chainedWorkflowRuntimeTracer.onWorkflowSessionStopped(session.sessionId)
96103
}
@@ -349,7 +356,7 @@ public class WorkflowRuntimeMonitor(
349356
* but we specify it as a [CascadeAction] as this is an action that is applied synchronously
350357
* as part of an action cascade that originated with a [QueuedAction].
351358
*
352-
* Note that for every [com.squareup.workflow1.Worker] a child workflow is created and rendered,
359+
* Note that for every [Worker] a child workflow is created and rendered,
353360
* so this will be part of the callstack for that. In that case the output of the handler will
354361
* contain the worker action signature. We can detect that with
355362
* [Worker.WORKER_OUTPUT_ACTION_NAME].

‎workflow-tracing/src/test/java/com/squareup/workflow1/tracing/WorkflowRuntimeMonitorTest.kt‎

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,196 @@ internal class WorkflowRuntimeMonitorTest {
653653
assertTrue(renderPassTracker.renderPassInfoReceived!!.renderCauseisRenderCause.Callback)
654654
}
655655

656+
@Test
657+
fun`onSessionCancelled logs dropped actions`() {
658+
val runtimeListener=TestWorkflowRuntimeLoopListener()
659+
val monitor=WorkflowRuntimeMonitor(
660+
runtimeName= runtimeName,
661+
workflowRuntimeTracers=listOf(fakeRuntimeTracer),
662+
runtimeLoopListener= runtimeListener
663+
)
664+
val testWorkflow=TestWorkflow()
665+
val rootSession= testWorkflow.createRootSession()
666+
val testScope=TestScope()
667+
668+
// Initialize session
669+
monitor.onSessionStarted(testScope, rootSession)
670+
671+
// Create some test actions
672+
val action1=TestAction("action1")
673+
val action2=TestAction("action2")
674+
val droppedActions=listOf(action1, action2)
675+
676+
// Call onSessionCancelled with dropped actions
677+
monitor.onSessionCancelled(
678+
cause=null,
679+
droppedActions= droppedActions,
680+
session= rootSession
681+
)
682+
683+
// Settle the runtime to flush updates
684+
monitor.onRuntimeUpdate(RuntimeSettled)
685+
686+
// Verify dropped actions were logged
687+
val updates= runtimeListener.runtimeUpdatesReceived!!.readAndClear()
688+
val droppedLogLines= updates.filterIsInstance<ActionDroppedLogLine>()
689+
690+
assertEquals(2, droppedLogLines.size)
691+
assertEquals("action1", droppedLogLines[0].actionName)
692+
assertEquals("action2", droppedLogLines[1].actionName)
693+
}
694+
695+
@Test
696+
fun`onSessionCancelled logs no actions when list is empty`() {
697+
val runtimeListener=TestWorkflowRuntimeLoopListener()
698+
val monitor=WorkflowRuntimeMonitor(
699+
runtimeName= runtimeName,
700+
workflowRuntimeTracers=listOf(fakeRuntimeTracer),
701+
runtimeLoopListener= runtimeListener
702+
)
703+
val testWorkflow=TestWorkflow()
704+
val rootSession= testWorkflow.createRootSession()
705+
val testScope=TestScope()
706+
707+
// Initialize session
708+
monitor.onSessionStarted(testScope, rootSession)
709+
710+
// Call onSessionCancelled with empty dropped actions list
711+
monitor.onSessionCancelled(
712+
cause=null,
713+
droppedActions= emptyList<WorkflowAction<String,String,String>>(),
714+
session= rootSession
715+
)
716+
717+
// Settle the runtime to flush updates
718+
monitor.onRuntimeUpdate(RuntimeSettled)
719+
720+
// Verify no dropped actions were logged
721+
val updates= runtimeListener.runtimeUpdatesReceived!!.readAndClear()
722+
val droppedLogLines= updates.filterIsInstance<ActionDroppedLogLine>()
723+
724+
assertEquals(0, droppedLogLines.size)
725+
}
726+
727+
@Test
728+
fun`onSessionCancelled calls tracer onWorkflowSessionStopped`() {
729+
val monitor=WorkflowRuntimeMonitor(
730+
runtimeName= runtimeName,
731+
workflowRuntimeTracers=listOf(fakeRuntimeTracer)
732+
)
733+
val testWorkflow=TestWorkflow()
734+
val rootSession= testWorkflow.createRootSession()
735+
val testScope=TestScope()
736+
737+
// Initialize session
738+
monitor.onSessionStarted(testScope, rootSession)
739+
740+
// Verify session is tracked
741+
assertEquals(1, monitor.workflowSessionInfo.size)
742+
743+
// Call onSessionCancelled
744+
monitor.onSessionCancelled(
745+
cause=null,
746+
droppedActions= emptyList<WorkflowAction<String,String,String>>(),
747+
session= rootSession
748+
)
749+
750+
// Verify session was removed from tracking
751+
assertEquals(0, monitor.workflowSessionInfo.size)
752+
assertTrue(fakeRuntimeTracer.onWorkflowSessionStoppedCalled)
753+
}
754+
755+
@Test
756+
fun`onSessionCancelled with CancellationException logs dropped actions`() {
757+
val runtimeListener=TestWorkflowRuntimeLoopListener()
758+
val monitor=WorkflowRuntimeMonitor(
759+
runtimeName= runtimeName,
760+
workflowRuntimeTracers=listOf(fakeRuntimeTracer),
761+
runtimeLoopListener= runtimeListener
762+
)
763+
val testWorkflow=TestWorkflow()
764+
val rootSession= testWorkflow.createRootSession()
765+
val testScope=TestScope()
766+
767+
// Initialize session
768+
monitor.onSessionStarted(testScope, rootSession)
769+
770+
// Create test actions
771+
val action1=TestAction("cancelledAction")
772+
val droppedActions=listOf(action1)
773+
774+
// Call onSessionCancelled with a CancellationException
775+
val cancellationException= kotlinx.coroutines.CancellationException("Test cancellation")
776+
monitor.onSessionCancelled(
777+
cause= cancellationException,
778+
droppedActions= droppedActions,
779+
session= rootSession
780+
)
781+
782+
// Settle the runtime to flush updates
783+
monitor.onRuntimeUpdate(RuntimeSettled)
784+
785+
// Verify dropped actions were logged even with cancellation exception
786+
val updates= runtimeListener.runtimeUpdatesReceived!!.readAndClear()
787+
val droppedLogLines= updates.filterIsInstance<ActionDroppedLogLine>()
788+
789+
assertEquals(1, droppedLogLines.size)
790+
assertEquals("cancelledAction", droppedLogLines[0].actionName)
791+
}
792+
793+
@Test
794+
fun`ActionDroppedLogLine formats correctly in log output`() {
795+
val actionName="testAction"
796+
val logLine=ActionDroppedLogLine(actionName)
797+
val builder=StringBuilder()
798+
799+
logLine.log(builder)
800+
801+
val expected="DROPPED:$actionName\n"
802+
assertEquals(expected, builder.toString())
803+
}
804+
805+
@Test
806+
fun`onSessionCancelled with multiple actions logs all in order`() {
807+
val runtimeListener=TestWorkflowRuntimeLoopListener()
808+
val monitor=WorkflowRuntimeMonitor(
809+
runtimeName= runtimeName,
810+
runtimeLoopListener= runtimeListener
811+
)
812+
val testWorkflow=TestWorkflow()
813+
val rootSession= testWorkflow.createRootSession()
814+
val testScope=TestScope()
815+
816+
// Initialize session
817+
monitor.onSessionStarted(testScope, rootSession)
818+
819+
// Create multiple test actions with distinct names
820+
val actions=listOf(
821+
TestAction("firstAction"),
822+
TestAction("secondAction"),
823+
TestAction("thirdAction")
824+
)
825+
826+
// Call onSessionCancelled with multiple dropped actions
827+
monitor.onSessionCancelled(
828+
cause=null,
829+
droppedActions= actions,
830+
session= rootSession
831+
)
832+
833+
// Settle the runtime to flush updates
834+
monitor.onRuntimeUpdate(RuntimeSettled)
835+
836+
// Verify all dropped actions were logged in order
837+
val updates= runtimeListener.runtimeUpdatesReceived!!.readAndClear()
838+
val droppedLogLines= updates.filterIsInstance<ActionDroppedLogLine>()
839+
840+
assertEquals(3, droppedLogLines.size)
841+
assertEquals("firstAction", droppedLogLines[0].actionName)
842+
assertEquals("secondAction", droppedLogLines[1].actionName)
843+
assertEquals("thirdAction", droppedLogLines[2].actionName)
844+
}
845+
656846
// Test helper classes
657847
privateclassTestWorkflow :StatefulWorkflow<String,String,String,String>() {
658848
overridefuninitialState(
@@ -749,6 +939,14 @@ internal class WorkflowRuntimeMonitorTest {
749939
}
750940
}
751941

942+
privateclassTestAction(name:String) : WorkflowAction<String, String, String>() {
943+
overridefun Updater.apply() {
944+
// No-op for testing
945+
}
946+
947+
overrideval debuggingName:String= name
948+
}
949+
752950
privateclassTestWorkflowRuntimeTracer :WorkflowRuntimeTracer() {
753951
var onWorkflowSessionStartedCalled=false
754952
var onWorkflowSessionStartedCallCount=0

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp