You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by ak...@apache.org on 2015/03/02 04:55:03 UTC

[03/14] incubator-ignite git commit: # IGNITE-11 Optimization obtaining localhosts.

# IGNITE-11 Optimization obtaining localhosts.


Project: http://git-wip-us.apache.org/repos/asf/incubator-ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ignite/commit/e89a70cc
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ignite/tree/e89a70cc
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ignite/diff/e89a70cc

Branch: refs/heads/ignite-187
Commit: e89a70cc911648b081b56c4c19e6f59d137b3a8e
Parents: e7171b0
Author: sevdokimov <se...@jetbrains.com>
Authored: Sun Feb 22 13:11:28 2015 +0300
Committer: sevdokimov <se...@jetbrains.com>
Committed: Sun Feb 22 13:11:28 2015 +0300

----------------------------------------------------------------------
 .../ignite/internal/util/IgniteUtils.java       | 87 +++++++++++++++++---
 1 file changed, 76 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ignite/blob/e89a70cc/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
----------------------------------------------------------------------
diff --git a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
index 5db0da4..4cf5718 100644
--- a/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
+++ b/modules/core/src/main/java/org/apache/ignite/internal/util/IgniteUtils.java
@@ -300,6 +300,8 @@ public abstract class IgniteUtils {
     private static final Map<Class<? extends IgniteCheckedException>, C1<IgniteCheckedException, IgniteException>>
         exceptionConverters;
 
+    private volatile static IgniteBiTuple<Collection<String>, Collection<String>> cachedLocalAddr;
+
     /**
      * Initializes enterprise check.
      */
@@ -1489,6 +1491,55 @@ public abstract class IgniteUtils {
         return locHost0 != null && !resetLocalHost().equals(locHost0);
     }
 
+    public static List<InetAddress> filterReachable(List<InetAddress> addrs) {
+        final int reachTimeout = 2000;
+
+        if (addrs.isEmpty())
+            return Collections.emptyList();
+
+        if (addrs.size() == 1) {
+            if (reachable(addrs.get(1), reachTimeout))
+                return Collections.singletonList(addrs.get(1));
+
+            return Collections.emptyList();
+        }
+
+        final List<InetAddress> res = new ArrayList<>(addrs.size());
+
+        Collection<Future<?>> futs = new ArrayList<>(addrs.size());
+
+        ExecutorService executor = Executors.newFixedThreadPool(Math.min(10, addrs.size()));
+
+        for (final InetAddress addr : addrs) {
+            futs.add(executor.submit(new Runnable() {
+                @Override
+                public void run() {
+                    if (reachable(addr, reachTimeout)) {
+                        synchronized (res) {
+                            res.add(addr);
+                        }
+                    }
+                }
+            }));
+        }
+
+        for (Future<?> fut : futs) {
+            try {
+                fut.get();
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+
+                throw new IgniteException("Thread has been interrupted.", e);
+            } catch (ExecutionException e) {
+                throw new IgniteException(e);
+            }
+        }
+
+        executor.shutdown();
+
+        return res;
+    }
+
     /**
      * Returns host names consistent with {@link #resolveLocalHost(String)}. So when it returns
      * a common address this method returns single host name, and when a wildcard address passed
@@ -1501,28 +1552,42 @@ public abstract class IgniteUtils {
      */
     public static IgniteBiTuple<Collection<String>, Collection<String>> resolveLocalAddresses(InetAddress locAddr)
         throws IOException, IgniteCheckedException {
+
         assert locAddr != null;
 
         Collection<String> addrs = new ArrayList<>();
         Collection<String> hostNames = new ArrayList<>();
 
         if (locAddr.isAnyLocalAddress()) {
-            // It should not take longer than 2 seconds to reach
-            // local address on any network.
-            int reachTimeout = 2000;
+            IgniteBiTuple<Collection<String>, Collection<String>> res = cachedLocalAddr;
 
-            for (NetworkInterface itf : asIterable(NetworkInterface.getNetworkInterfaces())) {
-                for (InetAddress addr : asIterable(itf.getInetAddresses())) {
-                    if (!addr.isLinkLocalAddress() && reachable(itf, addr, reachTimeout))
-                        addresses(addr, addrs, hostNames);
+            if (res == null) {
+                List<InetAddress> localAddrs = new ArrayList<>();
+
+                for (NetworkInterface itf : asIterable(NetworkInterface.getNetworkInterfaces())) {
+                    for (InetAddress addr : asIterable(itf.getInetAddresses())) {
+                        if (!addr.isLinkLocalAddress())
+                            localAddrs.add(addr);
+                    }
                 }
+
+                localAddrs = filterReachable(localAddrs);
+
+                for (InetAddress addr : localAddrs)
+                    addresses(addr, addrs, hostNames);
+
+                if (F.isEmpty(addrs))
+                    throw new IgniteCheckedException("No network addresses found (is networking enabled?).");
+
+                res = F.t(addrs, hostNames);
+
+                cachedLocalAddr = res;
             }
 
-            if (F.isEmpty(addrs))
-                throw new IgniteCheckedException("No network addresses found (is networking enabled?).");
+            return res;
         }
-        else
-            addresses(locAddr, addrs, hostNames);
+
+        addresses(locAddr, addrs, hostNames);
 
         return F.t(addrs, hostNames);
     }