You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ti...@apache.org on 2019/04/20 16:13:42 UTC

[maven-surefire] branch docker updated: algorithm been tolerant to long GC pauses prevent from killing JVM itself

This is an automated email from the ASF dual-hosted git repository.

tibordigana pushed a commit to branch docker
in repository https://gitbox.apache.org/repos/asf/maven-surefire.git


The following commit(s) were added to refs/heads/docker by this push:
     new 112f3e4  algorithm been tolerant to long GC pauses prevent from killing JVM itself
112f3e4 is described below

commit 112f3e4348f8ed731182064561604ff0fa9ca30c
Author: tibordigana <ti...@apache.org>
AuthorDate: Sat Apr 20 18:13:28 2019 +0200

    algorithm been tolerant to long GC pauses prevent from killing JVM itself
---
 .../apache/maven/surefire/booter/ForkedBooter.java | 26 ++++++++++++++++------
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
index 4e5bf86..f23e63d 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ForkedBooter.java
@@ -38,7 +38,7 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.Semaphore;
 import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicMarkableReference;
 
 import static java.lang.Math.max;
 import static java.lang.Thread.currentThread;
@@ -62,6 +62,8 @@ public final class ForkedBooter
 {
     private static final long DEFAULT_SYSTEM_EXIT_TIMEOUT_IN_SECONDS = 30L;
     private static final long PING_TIMEOUT_IN_SECONDS = 30L;
+    private static final long PING_TIMEOUT_MAX_DELAY_IN_SECONDS = 15L; // due to GC pauses
+    private static final long PING_MAX_TIMEOUT_IN_SECONDS = PING_TIMEOUT_IN_SECONDS + PING_TIMEOUT_MAX_DELAY_IN_SECONDS;
     private static final long ONE_SECOND_IN_MILLIS = 1000L;
     private static final String LAST_DITCH_SHUTDOWN_THREAD = "surefire-forkedjvm-last-ditch-daemon-shutdown-thread-";
     private static final String PING_THREAD = "surefire-forkedjvm-ping-";
@@ -175,7 +177,7 @@ public final class ForkedBooter
     private PingScheduler listenToShutdownCommands( Long ppid )
     {
         commandReader.addShutdownListener( createExitHandler() );
-        AtomicBoolean pingDone = new AtomicBoolean( true );
+        AtomicMarkableReference<Long> pingDone = new AtomicMarkableReference<>( System.currentTimeMillis(), true );
         commandReader.addNoopListener( createPingHandler( pingDone ) );
 
         PingScheduler pingMechanisms = new PingScheduler( createPingScheduler(),
@@ -219,14 +221,14 @@ public final class ForkedBooter
         };
     }
 
-    private CommandListener createPingHandler( final AtomicBoolean pingDone )
+    private CommandListener createPingHandler( final AtomicMarkableReference<Long> pingDone )
     {
         return new CommandListener()
         {
             @Override
             public void update( Command command )
             {
-                pingDone.set( true );
+                pingDone.set( System.currentTimeMillis(), true );
             }
         };
     }
@@ -257,7 +259,8 @@ public final class ForkedBooter
         };
     }
 
-    private Runnable createPingJob( final AtomicBoolean pingDone, final PpidChecker pluginProcessChecker  )
+    private Runnable createPingJob( final AtomicMarkableReference<Long> pingDone,
+                                    final PpidChecker pluginProcessChecker  )
     {
         return new Runnable()
         {
@@ -266,8 +269,17 @@ public final class ForkedBooter
             {
                 if ( !canUseNewPingMechanism( pluginProcessChecker ) )
                 {
-                    boolean hasPing = pingDone.getAndSet( false );
-                    if ( !hasPing )
+                    boolean hasPing;
+                    long lastCheck;
+                    do
+                    {
+                        hasPing = pingDone.isMarked();
+                        lastCheck = pingDone.getReference();
+                    } while ( pingDone.compareAndSet( lastCheck, lastCheck, false, hasPing ) );
+
+                    boolean longGcPausesDetected = System.currentTimeMillis() - lastCheck > PING_MAX_TIMEOUT_IN_SECONDS;
+
+                    if ( !longGcPausesDetected && !hasPing )
                     {
                         DumpErrorSingleton.getSingleton()
                                 .dumpText( "Killing self fork JVM. PING timeout elapsed." );