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 );
@@ -367,19 +381,25 @@ private void executeProcedure(Procedure<Env> proc) {
367381 }
368382 break ;
369383 }
370- lockState = acquireLock (proc );
371- switch (lockState ) {
372- case LOCK_ACQUIRED :
373- executeProcedure (rootProcStack , proc );
374- break ;
375- case LOCK_YIELD_WAIT :
376- case LOCK_EVENT_WAIT :
377- LOG .info (ProcedureMessages .LOCKSTATE_IS , proc , lockState );
378- break ;
379- default :
380- throw new UnsupportedOperationException ();
384+ try {
385+ lockState = acquireLock (proc );
386+ switch (lockState ) {
387+ case LOCK_ACQUIRED :
388+ executeProcedure (rootProcStack , proc );
389+ break ;
390+ case LOCK_YIELD_WAIT :
391+ case LOCK_EVENT_WAIT :
392+ LOG .info (ProcedureMessages .LOCKSTATE_IS , proc , lockState );
393+ if (lockState == ProcedureLockState .LOCK_EVENT_WAIT ) {
394+ lockEventWaitProcedure = proc ;
395+ }
396+ break ;
397+ default :
398+ throw new UnsupportedOperationException ();
399+ }
400+ } finally {
401+ rootProcStack .release ();
381402 }
382- rootProcStack .release ();
383403
384404 if (proc .isSuccess ()) {
385405 // update metrics on finishing the procedure
@@ -397,9 +417,9 @@ private void executeProcedure(Procedure<Env> proc) {
397417 } finally {
398418 // Only after procedure has completed execution can it be allowed to be rescheduled to prevent
399419 // 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 );
420+ if (lockEventWaitProcedure != null ) {
421+ LOG .info (ProcedureMessages .PROCEDUREID_WAIT_FOR_LOCK , lockEventWaitProcedure .getProcId ());
422+ lockEventWaitProcedure . waitForLock ( this .environment );
403423 }
404424 }
405425 }
@@ -607,8 +627,8 @@ private void yieldProcedure(Procedure<Env> proc) {
607627 * @param procedureStack root procedure stack
608628 * @return lock state
609629 */
610- private ProcedureLockState executeRootStackRollback (
611- Long rootProcId , RootProcedureStack procedureStack ) {
630+ private LockStateResult < Env > executeRootStackRollback (
631+ Long rootProcId , RootProcedureStack < Env > procedureStack ) {
612632 Procedure <Env > rootProcedure = procedures .get (rootProcId );
613633 ProcedureException exception = rootProcedure .getException ();
614634 if (exception == null ) {
@@ -629,19 +649,19 @@ private ProcedureLockState executeRootStackRollback(
629649 }
630650 ProcedureLockState lockState = acquireLock (procedure );
631651 if (lockState != ProcedureLockState .LOCK_ACQUIRED ) {
632- return lockState ;
652+ return new LockStateResult <>( lockState , procedure ) ;
633653 }
634654 lockState = executeRollback (procedure );
635655 releaseLock (procedure , false );
636656
637657 boolean abortRollback = lockState != ProcedureLockState .LOCK_ACQUIRED ;
638658 abortRollback |= !isRunning () || !store .isRunning ();
639659 if (abortRollback ) {
640- return lockState ;
660+ return new LockStateResult <>( lockState , procedure ) ;
641661 }
642662
643663 if (!procedure .isFinished () && procedure .isYieldAfterExecution (this .environment )) {
644- return ProcedureLockState .LOCK_YIELD_WAIT ;
664+ return new LockStateResult <>( ProcedureLockState .LOCK_YIELD_WAIT , procedure ) ;
645665 }
646666
647667 if (procedure != rootProcedure ) {
@@ -652,7 +672,7 @@ private ProcedureLockState executeRootStackRollback(
652672 LOG .info (
653673 ProcedureMessages .ROLLED_BACK_TIME_DURATION_IS , rootProcedure , rootProcedure .elapsedTime ());
654674 rootProcedureCleanup (rootProcedure );
655- return ProcedureLockState .LOCK_ACQUIRED ;
675+ return new LockStateResult <>( ProcedureLockState .LOCK_ACQUIRED , rootProcedure ) ;
656676 }
657677
658678 private ProcedureLockState acquireLock (Procedure <Env > proc ) {
@@ -787,21 +807,30 @@ public void run() {
787807 Thread .sleep (1000 );
788808 continue ;
789809 }
790- this .activeProcedure .set (procedure );
791- activeExecutorCount .incrementAndGet ();
792- startTime .set (System .currentTimeMillis ());
793- PROCEDURE_EXECUTION_CONTEXT .set (true );
794810 try {
795- executeProcedure (procedure );
796- } finally {
797- PROCEDURE_EXECUTION_CONTEXT .remove ();
811+ this .activeProcedure .set (procedure );
812+ activeExecutorCount .incrementAndGet ();
813+ startTime .set (System .currentTimeMillis ());
814+ try {
815+ PROCEDURE_EXECUTION_CONTEXT .set (true );
816+ try {
817+ executeProcedure (procedure );
818+ } finally {
819+ PROCEDURE_EXECUTION_CONTEXT .remove ();
820+ }
821+ } finally {
822+ activeExecutorCount .decrementAndGet ();
823+ LOG .trace (
824+ "Halt pid={}, activeCount={}" , procedure .getProcId (), activeExecutorCount .get ());
825+ this .activeProcedure .set (null );
826+ lastUpdated = System .currentTimeMillis ();
827+ startTime .set (lastUpdated );
828+ }
829+ } catch (Exception e ) {
830+ LOG .warn (
831+ "Exception happened when worker {} execute procedure {}" , getName (), procedure , e );
832+ throw e ;
798833 }
799- activeExecutorCount .decrementAndGet ();
800- LOG .trace (
801- "Halt pid={}, activeCount={}" , procedure .getProcId (), activeExecutorCount .get ());
802- this .activeProcedure .set (null );
803- lastUpdated = System .currentTimeMillis ();
804- startTime .set (lastUpdated );
805834 }
806835
807836 } catch (Exception e ) {
0 commit comments