From cbfd48d5fa34de5bbf322ac831fc372b075a0aeb Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Tue, 12 Jan 2016 16:23:43 +0000 Subject: [PATCH] Make thread pool static and provide convenience wrappers Existing usages of the static methods should still work, and all usage is on a single background thread. Fixes gh-77 --- .../springframework/cloud/util/InetUtils.java | 159 ++++++------------ .../cloud/util/InetUtilsProperties.java | 5 - .../cloud/util/InetUtilsTests.java | 17 +- 3 files changed, 62 insertions(+), 119 deletions(-) diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/util/InetUtils.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/util/InetUtils.java index 8c6e2ec7..513c4803 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/util/InetUtils.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/util/InetUtils.java @@ -1,5 +1,6 @@ package org.springframework.cloud.util; +import java.io.Closeable; import java.io.IOException; import java.net.Inet4Address; import java.net.InetAddress; @@ -14,32 +15,54 @@ import java.util.concurrent.Future; import java.util.concurrent.ThreadFactory; import java.util.concurrent.TimeUnit; -import org.springframework.util.SystemPropertyUtils; - import lombok.Data; -import lombok.SneakyThrows; import lombok.extern.apachecommons.CommonsLog; /** * @author Spencer Gibb */ @CommonsLog -public class InetUtils { +public class InetUtils implements Closeable { - private final ExecutorService executorService; + // TODO: maybe shutdown the thread pool if it isn't being used? + private static ExecutorService executorService; private final InetUtilsProperties properties; + private static final InetUtils instance = new InetUtils(new InetUtilsProperties()); public InetUtils(final InetUtilsProperties properties) { this.properties = properties; - this.executorService = Executors.newSingleThreadExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(r); - thread.setName(properties.getExecutorThreadName()); - thread.setDaemon(true); - return thread; + } + + @Override + public void close() throws IOException { + if (executorService != null) { + synchronized (InetUtils.class) { + if (executorService != null) { + executorService.shutdown(); + executorService = null; + } } - }); + } + } + + private ExecutorService getExecutor() { + if (executorService == null) { + synchronized (InetUtils.class) { + if (executorService == null) { + executorService = Executors + .newSingleThreadExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + Thread thread = new Thread(r); + thread.setName(InetUtilsProperties.PREFIX); + thread.setDaemon(true); + return thread; + } + }); + } + } + } + return executorService; } public HostInfo findFirstNonLoopbackHostInfo() { @@ -104,7 +127,7 @@ public class InetUtils { public HostInfo convertAddress(final InetAddress address) { HostInfo hostInfo = new HostInfo(); - Future result = this.executorService.submit(new Callable() { + Future result = getExecutor().submit(new Callable() { @Override public String call() throws Exception { return address.getHostName(); @@ -124,102 +147,20 @@ public class InetUtils { return hostInfo; } - @Deprecated - private static ExecutorService executor = Executors - .newSingleThreadExecutor(new ThreadFactory() { - @Override - public Thread newThread(Runnable r) { - Thread thread = new Thread(r); - thread.setName("spring.cloud.inetutils"); - thread.setDaemon(true); - return thread; - } - }); - /** - * Find the first non-loopback host info. If there were errors return a hostinfo with + * Find the first non-loopback host info. If there were errors return a host info with * 'localhost' and '127.0.0.1' for hostname and ipAddress respectively. */ - @Deprecated public static HostInfo getFirstNonLoopbackHostInfo() { - InetAddress address = getFirstNonLoopbackAddress(); - if (address != null) { - return convert(address); - } - HostInfo hostInfo = new HostInfo(); - hostInfo.setHostname("localhost"); - hostInfo.setIpAddress("127.0.0.1"); - return hostInfo; + return instance.findFirstNonLoopbackHostInfo(); } - /** - * Find the first non-loopback InetAddress - */ - @SneakyThrows - @Deprecated - public static InetAddress getFirstNonLoopbackAddress() { - try { - for (Enumeration enumNic = NetworkInterface - .getNetworkInterfaces(); enumNic.hasMoreElements();) { - NetworkInterface ifc = enumNic.nextElement(); - if (ifc.isUp()) { - log.trace("Testing interface: " + ifc.getDisplayName()); - for (Enumeration enumAddr = ifc - .getInetAddresses(); enumAddr.hasMoreElements();) { - InetAddress address = enumAddr.nextElement(); - if (address instanceof Inet4Address - && !address.isLoopbackAddress()) { - log.trace("Found non-loopback interface: " - + ifc.getDisplayName()); - return address; - } - } - } - } - } - catch (IOException ex) { - log.error("Cannot get first non-loopback address", ex); - } - - try { - return InetAddress.getLocalHost(); - } - catch (UnknownHostException e) { - log.warn("Unable to retrieve localhost"); - } - - return null; - } - - @Deprecated public static HostInfo convert(final InetAddress address) { - HostInfo hostInfo = new HostInfo(); - Future result = executor.submit(new Callable() { - @Override - public String call() throws Exception { - return address.getHostName(); - } - }); + return instance.convertAddress(address); + } - String hostname; - try { - String value = SystemPropertyUtils.resolvePlaceholders( - "${spring.util.timeout.sec:${SPRING_UTIL_TIMEOUT_SEC:1}}"); - int timeout = 1; - try { - timeout = Integer.valueOf(value); - } - catch (NumberFormatException e) { - } - hostname = result.get(timeout, TimeUnit.SECONDS); - } - catch (Exception e) { - log.info("Cannot determine local hostname"); - hostname = "localhost"; - } - hostInfo.setHostname(hostname); - hostInfo.setIpAddress(address.getHostAddress()); - return hostInfo; + public static int getIpAddressAsInt(String host) { + return new HostInfo(host).getIpAddressAsInt(); } @Data @@ -228,10 +169,21 @@ public class InetUtils { private String ipAddress; private String hostname; + HostInfo(String hostname) { + this.hostname = hostname; + } + + HostInfo() { + } + public int getIpAddressAsInt() { InetAddress inetAddress = null; + String host = this.ipAddress; + if (host == null) { + host = this.hostname; + } try { - inetAddress = InetAddress.getByName(this.ipAddress); + inetAddress = InetAddress.getByName(host); } catch (final UnknownHostException e) { throw new IllegalArgumentException(e); @@ -239,4 +191,5 @@ public class InetUtils { return ByteBuffer.wrap(inetAddress.getAddress()).getInt(); } } + } diff --git a/spring-cloud-commons/src/main/java/org/springframework/cloud/util/InetUtilsProperties.java b/spring-cloud-commons/src/main/java/org/springframework/cloud/util/InetUtilsProperties.java index 703462b8..99771b76 100644 --- a/spring-cloud-commons/src/main/java/org/springframework/cloud/util/InetUtilsProperties.java +++ b/spring-cloud-commons/src/main/java/org/springframework/cloud/util/InetUtilsProperties.java @@ -16,11 +16,6 @@ import lombok.Data; public class InetUtilsProperties { public static final String PREFIX = "spring.cloud.inetutils"; - /** - * Name of InetUtils executor thread - */ - private String executorThreadName = PREFIX; - /** * The default hostname. Used in case of errors. */ diff --git a/spring-cloud-commons/src/test/java/org/springframework/cloud/util/InetUtilsTests.java b/spring-cloud-commons/src/test/java/org/springframework/cloud/util/InetUtilsTests.java index c1548abd..99a4f19f 100644 --- a/spring-cloud-commons/src/test/java/org/springframework/cloud/util/InetUtilsTests.java +++ b/spring-cloud-commons/src/test/java/org/springframework/cloud/util/InetUtilsTests.java @@ -34,22 +34,20 @@ public class InetUtilsTests { @Test public void testGetFirstNonLoopbackHostInfo() { - assertNotNull(new InetUtils(new InetUtilsProperties()) - .findFirstNonLoopbackHostInfo()); - assertNotNull(InetUtils.getFirstNonLoopbackHostInfo()); + assertNotNull( + new InetUtils(new InetUtilsProperties()).findFirstNonLoopbackHostInfo()); } @Test public void testGetFirstNonLoopbackAddress() { - assertNotNull(new InetUtils(new InetUtilsProperties()) - .findFirstNonLoopbackAddress()); - assertNotNull(InetUtils.getFirstNonLoopbackAddress()); + assertNotNull( + new InetUtils(new InetUtilsProperties()).findFirstNonLoopbackAddress()); } @Test public void testConvert() throws Exception { - assertNotNull(new InetUtils(new InetUtilsProperties()).convertAddress(InetAddress - .getByName("localhost"))); + assertNotNull(new InetUtils(new InetUtilsProperties()) + .convertAddress(InetAddress.getByName("localhost"))); assertNotNull(InetUtils.convert(InetAddress.getByName("localhost"))); } @@ -58,9 +56,6 @@ public class InetUtilsTests { HostInfo info = new InetUtils(new InetUtilsProperties()) .findFirstNonLoopbackHostInfo(); assertNotNull(info.getIpAddressAsInt()); - - info = InetUtils.getFirstNonLoopbackHostInfo(); - assertNotNull(info.getIpAddressAsInt()); } @Test