1818package org .apache .seatunnel .engine .server .checkpoint ;
1919
2020import org .apache .seatunnel .common .utils .ReflectionUtils ;
21- import org .apache .seatunnel .engine .checkpoint .storage .exception . CheckpointStorageException ;
21+ import org .apache .seatunnel .engine .checkpoint .storage .api . CheckpointStorage ;
2222import org .apache .seatunnel .engine .common .config .server .CheckpointConfig ;
2323import org .apache .seatunnel .engine .common .config .server .CheckpointStorageConfig ;
2424import org .apache .seatunnel .engine .common .utils .concurrent .CompletableFuture ;
2828import org .apache .seatunnel .engine .server .execution .TaskGroupLocation ;
2929import org .apache .seatunnel .engine .server .execution .TaskLocation ;
3030import org .apache .seatunnel .engine .server .master .JobMaster ;
31+ import org .apache .seatunnel .engine .server .task .operation .TaskOperation ;
32+ import org .apache .seatunnel .engine .server .task .statemachine .SeaTunnelTaskState ;
3133
3234import org .junit .jupiter .api .Assertions ;
3335import org .junit .jupiter .api .Test ;
3436import org .mockito .MockedStatic ;
3537import org .mockito .Mockito ;
3638
39+ import com .hazelcast .jet .datamodel .Tuple2 ;
40+ import com .hazelcast .map .IMap ;
41+ import com .hazelcast .spi .impl .NodeEngine ;
3742import com .hazelcast .spi .impl .operationservice .impl .InvocationFuture ;
3843
3944import java .time .Instant ;
4045import java .util .ArrayList ;
46+ import java .util .Arrays ;
4147import java .util .Collections ;
4248import java .util .HashMap ;
49+ import java .util .HashSet ;
50+ import java .util .List ;
4351import java .util .Map ;
52+ import java .util .Set ;
4453import java .util .concurrent .ExecutionException ;
4554import java .util .concurrent .ExecutorService ;
4655import java .util .concurrent .Executors ;
@@ -54,7 +63,7 @@ public class CheckpointCoordinatorTest
5463 extends AbstractSeaTunnelServerTest <CheckpointCoordinatorTest > {
5564
5665 @ Test
57- void testACKNotExistPendingCheckpoint () throws CheckpointStorageException {
66+ void testACKNotExistPendingCheckpoint () {
5867 CheckpointConfig checkpointConfig = new CheckpointConfig ();
5968 checkpointConfig .setStorage (new CheckpointStorageConfig ());
6069 Map <Integer , CheckpointPlan > planMap = new HashMap <>();
@@ -80,8 +89,7 @@ void testACKNotExistPendingCheckpoint() throws CheckpointStorageException {
8089
8190 @ Test
8291 void testSchedulerThreadShouldNotBeInterruptedBeforeJobMasterCleaned ()
83- throws CheckpointStorageException , ExecutionException , InterruptedException ,
84- TimeoutException {
92+ throws ExecutionException , InterruptedException , TimeoutException {
8593 CheckpointConfig checkpointConfig = new CheckpointConfig ();
8694 // quickly fail the checkpoint
8795 checkpointConfig .setCheckpointTimeout (5000 );
@@ -122,8 +130,7 @@ protected void handleCheckpointError(int pipelineId, boolean neverRestore) {
122130
123131 @ Test
124132 void testCheckpointContinuesWorkAfterClockDrift ()
125- throws CheckpointStorageException , ExecutionException , InterruptedException ,
126- TimeoutException {
133+ throws ExecutionException , InterruptedException , TimeoutException {
127134 CheckpointConfig checkpointConfig = new CheckpointConfig ();
128135 checkpointConfig .setStorage (new CheckpointStorageConfig ());
129136 checkpointConfig .setCheckpointTimeout (5000 );
@@ -169,9 +176,7 @@ protected void handleCheckpointError(int pipelineId, boolean neverRestore) {
169176 }
170177
171178 @ Test
172- void testCheckpointMinPause ()
173- throws CheckpointStorageException , ExecutionException , InterruptedException ,
174- TimeoutException {
179+ void testCheckpointMinPause () {
175180 CheckpointConfig checkpointConfig = new CheckpointConfig ();
176181 checkpointConfig .setStorage (new CheckpointStorageConfig ());
177182 checkpointConfig .setCheckpointInterval (10000 ); // 10 seconds
@@ -280,4 +285,113 @@ public CheckpointCoordinator getCheckpointCoordinator(int pipelineId) {
280285 executorService .shutdownNow ();
281286 }
282287 }
288+
289+ @ Test
290+ void testFilteringClosedTasksAndActions () {
291+ CheckpointConfig checkpointConfig = new CheckpointConfig ();
292+ checkpointConfig .setStorage (new CheckpointStorageConfig ());
293+ Map <Integer , CheckpointPlan > planMap = new HashMap <>();
294+ planMap .put (1 , CheckpointPlan .builder ().pipelineId (1 ).build ());
295+ TestCheckpointManager checkpointManager =
296+ new TestCheckpointManager (
297+ 1L ,
298+ nodeEngine ,
299+ planMap ,
300+ checkpointConfig ,
301+ server .getCheckpointService ().getCheckpointStorage (),
302+ instance .getExecutorService ("test" ),
303+ nodeEngine .getHazelcastInstance ().getMap (IMAP_RUNNING_JOB_STATE ));
304+
305+ TaskGroupLocation group1 = new TaskGroupLocation (1L , 1 , 1 );
306+ TaskLocation task1 = new TaskLocation (group1 , 1 , 1 );
307+ TaskLocation task2 = new TaskLocation (group1 , 2 , 1 );
308+
309+ ActionStateKey actionKey1 = new ActionStateKey ("action1" );
310+ ActionStateKey actionKey2 = new ActionStateKey ("action2" );
311+
312+ Map <TaskLocation , Set <Tuple2 <ActionStateKey , Integer >>> subtaskActions = new HashMap <>();
313+ subtaskActions .put (task1 , new HashSet <>(Arrays .asList (Tuple2 .tuple2 (actionKey1 , 0 ))));
314+ subtaskActions .put (task2 , new HashSet <>(Arrays .asList (Tuple2 .tuple2 (actionKey2 , 0 ))));
315+
316+ Map <ActionStateKey , Integer > pipelineActions = new HashMap <>();
317+ pipelineActions .put (actionKey1 , 1 );
318+ pipelineActions .put (actionKey2 , 1 );
319+
320+ CheckpointPlan plan =
321+ CheckpointPlan .builder ()
322+ .pipelineId (1 )
323+ .pipelineSubtasks (new HashSet <>(Arrays .asList (task1 , task2 )))
324+ .startingSubtasks (new HashSet <>(Arrays .asList (task1 , task2 )))
325+ .subtaskActions (subtaskActions )
326+ .pipelineActions (pipelineActions )
327+ .build ();
328+
329+ ExecutorService executor = Executors .newSingleThreadExecutor ();
330+ CheckpointCoordinator coordinator =
331+ new CheckpointCoordinator (
332+ checkpointManager ,
333+ null ,
334+ checkpointConfig ,
335+ 1L ,
336+ plan ,
337+ null ,
338+ null ,
339+ executor ,
340+ Mockito .mock (com .hazelcast .map .IMap .class ),
341+ false );
342+
343+ Map <Long , SeaTunnelTaskState > taskStatus = coordinator .getPipelineTaskStatus ();
344+ taskStatus .put (task1 .getTaskID (), SeaTunnelTaskState .RUNNING );
345+ taskStatus .put (task2 .getTaskID (), SeaTunnelTaskState .CLOSED );
346+
347+ Map <ActionStateKey , ActionState > actionStates =
348+ (Map <ActionStateKey , ActionState >)
349+ ReflectionUtils .invoke (coordinator , "getActionStates" );
350+ Assertions .assertTrue (actionStates .containsKey (actionKey1 ));
351+ Assertions .assertFalse (actionStates .containsKey (actionKey2 ));
352+
353+ Map <Long , TaskStatistics > stats =
354+ (Map <Long , TaskStatistics >)
355+ ReflectionUtils .invoke (coordinator , "getTaskStatistics" );
356+ Assertions .assertTrue (stats .containsKey (task1 .getTaskID ()));
357+ Assertions .assertFalse (stats .containsKey (task2 .getTaskID ()));
358+
359+ CheckpointBarrier barrier =
360+ new CheckpointBarrier (
361+ 1L , System .currentTimeMillis (), CheckpointType .CHECKPOINT_TYPE );
362+ coordinator .triggerCheckpoint (barrier );
363+ Assertions .assertEquals (1 , checkpointManager .operations .size ());
364+
365+ executor .shutdownNow ();
366+ }
367+ }
368+
369+ class TestCheckpointManager extends CheckpointManager {
370+ public List <TaskOperation > operations = new ArrayList <>();
371+
372+ public TestCheckpointManager (
373+ long jobId ,
374+ NodeEngine nodeEngine ,
375+ Map <Integer , CheckpointPlan > checkpointPlanMap ,
376+ CheckpointConfig checkpointConfig ,
377+ CheckpointStorage checkpointStorage ,
378+ ExecutorService executorService ,
379+ IMap <Object , Object > runningJobStateIMap ) {
380+ super (
381+ jobId ,
382+ false ,
383+ nodeEngine ,
384+ null ,
385+ checkpointPlanMap ,
386+ checkpointConfig ,
387+ checkpointStorage ,
388+ executorService ,
389+ runningJobStateIMap );
390+ }
391+
392+ @ Override
393+ protected InvocationFuture <?> sendOperationToMemberNode (TaskOperation operation ) {
394+ this .operations .add (operation );
395+ return null ;
396+ }
283397}
0 commit comments