File calculate-fqdns-in-parallel-to-avoid-blockings-bsc-1.patch of Package salt

From 722b9395a6489da7626e6a388c78bf8e8812190e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
 <psuarezhernandez@suse.com>
Date: Fri, 12 Apr 2019 16:47:03 +0100
Subject: [PATCH] Calculate FQDNs in parallel to avoid blockings (bsc#1129079)

Fix pylint issue
---
 salt/grains/core.py | 31 ++++++++++++++++++++++++++-----
 1 file changed, 26 insertions(+), 5 deletions(-)

diff --git a/salt/grains/core.py b/salt/grains/core.py
index 05a9d5035d..796458939d 100644
--- a/salt/grains/core.py
+++ b/salt/grains/core.py
@@ -20,11 +20,14 @@ import platform
 import logging
 import locale
 import uuid
+import time
 import zlib
 from errno import EACCES, EPERM
 import datetime
 import warnings
 
+from multiprocessing.dummy import Pool as ThreadPool
+
 # pylint: disable=import-error
 try:
     import dateutil.tz
@@ -2200,13 +2203,10 @@ def fqdns():
     grains = {}
     fqdns = set()
 
-    addresses = salt.utils.network.ip_addrs(include_loopback=False, interface_data=_get_interfaces())
-    addresses.extend(salt.utils.network.ip_addrs6(include_loopback=False, interface_data=_get_interfaces()))
-    err_message = 'Exception during resolving address: %s'
-    for ip in addresses:
+    def _lookup_fqdn(ip):
         try:
             name, aliaslist, addresslist = socket.gethostbyaddr(ip)
-            fqdns.update([socket.getfqdn(name)] + [als for als in aliaslist if salt.utils.network.is_fqdn(als)])
+            return [socket.getfqdn(name)] + [als for als in aliaslist if salt.utils.network.is_fqdn(als)]
         except socket.herror as err:
             if err.errno == 0:
                 # No FQDN for this IP address, so we don't need to know this all the time.
@@ -2216,6 +2216,27 @@ def fqdns():
         except (socket.error, socket.gaierror, socket.timeout) as err:
             log.error(err_message, err)
 
+    start = time.time()
+
+    addresses = salt.utils.network.ip_addrs(include_loopback=False, interface_data=_get_interfaces())
+    addresses.extend(salt.utils.network.ip_addrs6(include_loopback=False, interface_data=_get_interfaces()))
+    err_message = 'Exception during resolving address: %s'
+
+    # Create a ThreadPool to process the underlying calls to 'socket.gethostbyaddr' in parallel.
+    # This avoid blocking the execution when the "fqdn" is not defined for certains IP addresses, which was causing
+    # that "socket.timeout" was reached multiple times secuencially, blocking execution for several seconds.
+    pool = ThreadPool(8)
+    results = pool.map(_lookup_fqdn, addresses)
+    pool.close()
+    pool.join()
+
+    for item in results:
+        if item:
+            fqdns.update(item)
+
+    elapsed = time.time() - start
+    log.debug('Elapsed time getting FQDNs: {} seconds'.format(elapsed))
+
     return {"fqdns": sorted(list(fqdns))}
 
 
-- 
2.17.1