diff --git a/src/main/java/org/mule/service/http/impl/service/HttpServiceImplementation.java b/src/main/java/org/mule/service/http/impl/service/HttpServiceImplementation.java index 421450f1..c240f03f 100644 --- a/src/main/java/org/mule/service/http/impl/service/HttpServiceImplementation.java +++ b/src/main/java/org/mule/service/http/impl/service/HttpServiceImplementation.java @@ -6,12 +6,9 @@ */ package org.mule.service.http.impl.service; -import static java.util.Optional.empty; -import static java.util.Optional.of; -import static org.glassfish.grizzly.CloseReason.LOCALLY_CLOSED_REASON; -import static org.glassfish.grizzly.CloseReason.REMOTELY_CLOSED_REASON; import static org.mule.runtime.api.i18n.I18nMessageFactory.createStaticMessage; import static org.mule.runtime.api.scheduler.SchedulerConfig.config; +import static org.mule.runtime.api.util.MuleSystemProperties.SYSTEM_PROPERTY_PREFIX; import static org.mule.runtime.core.api.config.MuleProperties.APP_NAME_PROPERTY; import static org.mule.runtime.core.api.config.MuleProperties.DOMAIN_NAME_PROPERTY; import static org.mule.runtime.core.api.config.MuleProperties.OBJECT_SCHEDULER_BASE_CONFIG; @@ -20,7 +17,15 @@ import static org.mule.runtime.core.api.config.bootstrap.ArtifactType.POLICY; import static org.mule.runtime.core.api.lifecycle.LifecycleUtils.disposeIfNeeded; import static org.mule.runtime.core.api.lifecycle.LifecycleUtils.initialiseIfNeeded; + +import static java.lang.Long.getLong; +import static java.util.Optional.empty; +import static java.util.Optional.of; + +import static org.glassfish.grizzly.CloseReason.LOCALLY_CLOSED_REASON; +import static org.glassfish.grizzly.CloseReason.REMOTELY_CLOSED_REASON; import static org.slf4j.LoggerFactory.getLogger; + import org.mule.runtime.api.artifact.Registry; import org.mule.runtime.api.exception.MuleException; import org.mule.runtime.api.lifecycle.Startable; @@ -65,6 +70,8 @@ public class HttpServiceImplementation implements HttpService, Startable, Stoppa private static final Logger logger = getLogger(HttpServiceImplementation.class); private static final String CONTAINER_CONTEXT = "container"; + private static final String HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_PROPERTY_NAME = + SYSTEM_PROPERTY_PREFIX + "http.graceful.shutdown.timeout"; private static final long DEFAULT_SHUTDOWN_TIMEOUT = 200; protected final SchedulerService schedulerService; @@ -80,8 +87,8 @@ public HttpServiceImplementation(SchedulerService schedulerService) { @Override public HttpServerFactory getServerFactory() { - return new ContextHttpServerFactoryAdapter(CONTAINER_CONTEXT, empty(), listenerConnectionManager, - () -> DEFAULT_SHUTDOWN_TIMEOUT); + Supplier shutdownTimeout = () -> getLong(HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_PROPERTY_NAME, DEFAULT_SHUTDOWN_TIMEOUT); + return new ContextHttpServerFactoryAdapter(CONTAINER_CONTEXT, empty(), listenerConnectionManager, shutdownTimeout); } @Inject @@ -89,7 +96,8 @@ public HttpServerFactory getServerFactory(Registry registry, MuleContext muleCon ArtifactType artifactType = muleContext.getArtifactType(); Optional appName = registry.lookupByName(APP_NAME_PROPERTY); Optional domainName = registry.lookupByName(DOMAIN_NAME_PROPERTY); - Supplier shutdownTimeout = () -> muleContext.getConfiguration().getShutdownTimeout(); + Supplier shutdownTimeout = + () -> getLong(HTTP_GRACEFUL_SHUTDOWN_TIMEOUT_PROPERTY_NAME, muleContext.getConfiguration().getShutdownTimeout()); try { switch (artifactType) { diff --git a/src/main/java/org/mule/service/http/impl/service/server/grizzly/GrizzlyHttpServer.java b/src/main/java/org/mule/service/http/impl/service/server/grizzly/GrizzlyHttpServer.java index 7c38593b..28fd461e 100644 --- a/src/main/java/org/mule/service/http/impl/service/server/grizzly/GrizzlyHttpServer.java +++ b/src/main/java/org/mule/service/http/impl/service/server/grizzly/GrizzlyHttpServer.java @@ -6,6 +6,11 @@ */ package org.mule.service.http.impl.service.server.grizzly; +import static org.mule.runtime.api.util.MuleSystemProperties.MULE_LOG_SEPARATION_DISABLED; +import static org.mule.runtime.core.api.util.ClassUtils.setContextClassLoader; +import static org.mule.runtime.http.api.server.MethodRequestMatcher.acceptAll; +import static org.mule.service.http.impl.service.server.grizzly.MuleSslFilter.createSslFilter; + import static java.lang.Math.min; import static java.lang.String.format; import static java.lang.System.getProperty; @@ -14,10 +19,7 @@ import static java.util.Collections.synchronizedList; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.NANOSECONDS; -import static org.mule.runtime.api.util.MuleSystemProperties.MULE_LOG_SEPARATION_DISABLED; -import static org.mule.runtime.core.api.util.ClassUtils.setContextClassLoader; -import static org.mule.runtime.http.api.server.MethodRequestMatcher.acceptAll; -import static org.mule.service.http.impl.service.server.grizzly.MuleSslFilter.createSslFilter; + import org.mule.runtime.api.scheduler.Scheduler; import org.mule.runtime.api.tls.TlsContextFactory; import org.mule.runtime.http.api.HttpConstants.Protocol; @@ -53,6 +55,8 @@ public class GrizzlyHttpServer implements HttpServer, Supplier { protected static final Logger logger = LoggerFactory.getLogger(GrizzlyHttpServer.class); + public static final int WAIT_FOREVER_FOR_CONNECTIONS_TO_CLOSE = -1; + public static final int WAIT_FOR_CONNECTIONS_INTERVAL = 50; private static boolean REPLACE_CONTEXT_CLASSLOADER = getProperty(MULE_LOG_SEPARATION_DISABLED) == null; private final TCPNIOTransport transport; @@ -119,13 +123,13 @@ public synchronized HttpServer stop() { if (shutdownTimeout != 0) { synchronized (clientConnections) { - long remainingMillis = NANOSECONDS.toMillis(stopNanos - nanoTime()); + long remainingMillis = getRemainingMillisToWait(stopNanos, shutdownTimeout); while (!clientConnections.isEmpty() && remainingMillis > 0) { - long millisToWait = min(remainingMillis, 50); + long millisToWait = min(remainingMillis, WAIT_FOR_CONNECTIONS_INTERVAL); logger.debug("There are still {} open connections on server stop. Waiting {} milliseconds", clientConnections.size(), millisToWait); clientConnections.wait(millisToWait); - remainingMillis = NANOSECONDS.toMillis(stopNanos - nanoTime()); + remainingMillis = getRemainingMillisToWait(stopNanos, shutdownTimeout); } if (!clientConnections.isEmpty()) { @@ -146,6 +150,14 @@ public synchronized HttpServer stop() { return this; } + private static long getRemainingMillisToWait(long stopNanos, Long shutdownTimeout) { + if (shutdownTimeout == WAIT_FOREVER_FOR_CONNECTIONS_TO_CLOSE) { + return WAIT_FOR_CONNECTIONS_INTERVAL; + } else { + return NANOSECONDS.toMillis(stopNanos - nanoTime()); + } + } + @Override public void dispose() { // Nothing to do