2323import org .apache .iotdb .commons .utils .RetryUtils ;
2424import org .apache .iotdb .commons .utils .TestOnly ;
2525import org .apache .iotdb .confignode .i18n .ProcedureMessages ;
26- import org .apache .iotdb .confignode .procedure .env .ConfigNodeProcedureEnv ;
2726import org .apache .iotdb .confignode .procedure .exception .ProcedureException ;
2827import org .apache .iotdb .confignode .procedure .scheduler .ProcedureScheduler ;
2928import org .apache .iotdb .confignode .procedure .scheduler .SimpleProcedureScheduler ;
4241import java .util .Deque ;
4342import java .util .HashSet ;
4443import java .util .List ;
45- import java .util .Objects ;
4644import java .util .Set ;
4745import java .util .concurrent .ConcurrentHashMap ;
4846import java .util .concurrent .CopyOnWriteArrayList ;
@@ -86,6 +84,16 @@ public class ProcedureExecutor<Env> {
8684 private final Env environment ;
8785 private final IProcedureStore <Env > store ;
8886
87+ private static final class LockStateResult <Env > {
88+ private final ProcedureLockState lockState ;
89+ private final Procedure <Env > procedure ;
90+
91+ private LockStateResult (ProcedureLockState lockState , Procedure <Env > procedure ) {
92+ this .lockState = lockState ;
93+ this .procedure = procedure ;
94+ }
95+ }
96+
8997 public ProcedureExecutor (
9098 final Env environment , final IProcedureStore <Env > store , final ProcedureScheduler scheduler ) {
9199 this .environment = environment ;
@@ -329,33 +337,39 @@ private void executeProcedure(Procedure<Env> proc) {
329337 return ;
330338 }
331339 ProcedureLockState lockState = null ;
340+ Procedure <Env > lockEventWaitProcedure = null ;
332341 try {
333342 do {
334343 if (!rootProcStack .acquire ()) {
335344 if (rootProcStack .setRollback ()) {
336- lockState = executeRootStackRollback (rootProcId , rootProcStack );
345+ LockStateResult <Env > lockStateResult =
346+ executeRootStackRollback (rootProcId , rootProcStack );
347+ lockState = lockStateResult .lockState ;
337348 switch (lockState ) {
338349 case LOCK_ACQUIRED :
339350 break ;
340351 case LOCK_EVENT_WAIT :
341- LOG .info (ProcedureMessages .LOCK_EVENT_WAIT_ROLLBACK , proc );
352+ LOG .info (ProcedureMessages .LOCK_EVENT_WAIT_ROLLBACK , lockStateResult . procedure );
342353 rootProcStack .unsetRollback ();
354+ lockEventWaitProcedure = lockStateResult .procedure ;
343355 break ;
344356 case LOCK_YIELD_WAIT :
345357 rootProcStack .unsetRollback ();
346- scheduler .yield (proc );
358+ scheduler .yield (lockStateResult . procedure );
347359 break ;
348360 default :
349361 throw new UnsupportedOperationException ();
350362 }
351363 } else {
352364 if (!proc .wasExecuted ()) {
353- switch (executeRollback (proc )) {
365+ lockState = executeRollback (proc );
366+ switch (lockState ) {
354367 case LOCK_ACQUIRED :
355368 break ;
356369 case LOCK_EVENT_WAIT :
357370 LOG .info (
358371 ProcedureMessages .LOCK_EVENT_WAIT_CAN_T_ROLLBACK_CHILD_RUNNING_FOR , proc );
372+ lockEventWaitProcedure = proc ;
359373 break ;
360374 case LOCK_YIELD_WAIT :
361375 scheduler .yield (proc );
@@ -375,6 +389,9 @@ private void executeProcedure(Procedure<Env> proc) {
375389 case LOCK_YIELD_WAIT :
376390 case LOCK_EVENT_WAIT :
377391 LOG .info (ProcedureMessages .LOCKSTATE_IS , proc , lockState );
392+ if (lockState == ProcedureLockState .LOCK_EVENT_WAIT ) {
393+ lockEventWaitProcedure = proc ;
394+ }
378395 break ;
379396 default :
380397 throw new UnsupportedOperationException ();
@@ -397,9 +414,9 @@ private void executeProcedure(Procedure<Env> proc) {
397414 } finally {
398415 // Only after procedure has completed execution can it be allowed to be rescheduled to prevent
399416 // data races
400- if (Objects . equals ( lockState , ProcedureLockState . LOCK_EVENT_WAIT ) ) {
401- LOG .info (ProcedureMessages .PROCEDUREID_WAIT_FOR_LOCK , proc .getProcId ());
402- (( ConfigNodeProcedureEnv ) this .environment ). getNodeLock (). waitProcedure ( proc );
417+ if (lockEventWaitProcedure != null ) {
418+ LOG .info (ProcedureMessages .PROCEDUREID_WAIT_FOR_LOCK , lockEventWaitProcedure .getProcId ());
419+ lockEventWaitProcedure . waitForLock ( this .environment );
403420 }
404421 }
405422 }
@@ -607,8 +624,8 @@ private void yieldProcedure(Procedure<Env> proc) {
607624 * @param procedureStack root procedure stack
608625 * @return lock state
609626 */
610- private ProcedureLockState executeRootStackRollback (
611- Long rootProcId , RootProcedureStack procedureStack ) {
627+ private LockStateResult < Env > executeRootStackRollback (
628+ Long rootProcId , RootProcedureStack < Env > procedureStack ) {
612629 Procedure <Env > rootProcedure = procedures .get (rootProcId );
613630 ProcedureException exception = rootProcedure .getException ();
614631 if (exception == null ) {
@@ -629,19 +646,19 @@ private ProcedureLockState executeRootStackRollback(
629646 }
630647 ProcedureLockState lockState = acquireLock (procedure );
631648 if (lockState != ProcedureLockState .LOCK_ACQUIRED ) {
632- return lockState ;
649+ return new LockStateResult <>( lockState , procedure ) ;
633650 }
634651 lockState = executeRollback (procedure );
635652 releaseLock (procedure , false );
636653
637654 boolean abortRollback = lockState != ProcedureLockState .LOCK_ACQUIRED ;
638655 abortRollback |= !isRunning () || !store .isRunning ();
639656 if (abortRollback ) {
640- return lockState ;
657+ return new LockStateResult <>( lockState , procedure ) ;
641658 }
642659
643660 if (!procedure .isFinished () && procedure .isYieldAfterExecution (this .environment )) {
644- return ProcedureLockState .LOCK_YIELD_WAIT ;
661+ return new LockStateResult <>( ProcedureLockState .LOCK_YIELD_WAIT , procedure ) ;
645662 }
646663
647664 if (procedure != rootProcedure ) {
@@ -652,7 +669,7 @@ private ProcedureLockState executeRootStackRollback(
652669 LOG .info (
653670 ProcedureMessages .ROLLED_BACK_TIME_DURATION_IS , rootProcedure , rootProcedure .elapsedTime ());
654671 rootProcedureCleanup (rootProcedure );
655- return ProcedureLockState .LOCK_ACQUIRED ;
672+ return new LockStateResult <>( ProcedureLockState .LOCK_ACQUIRED , rootProcedure ) ;
656673 }
657674
658675 private ProcedureLockState acquireLock (Procedure <Env > proc ) {
0 commit comments