Browse Source

AMBARI-5633. Start Services command gets stuck for about 30 mins (dlysnichenko)

Lisnichenko Dmitro 11 years ago
parent
commit
9a245cbc4e

+ 4 - 1
ambari-agent/src/main/python/ambari_agent/CommandStatusDict.py

@@ -49,11 +49,14 @@ class CommandStatusDict():
     """
     if 'taskId' in command:
       key = command['taskId']
+      status_command = False
     else: # Status command reports has no task id
       key = id(command)
+      status_command = True
     with self.lock: # Synchronized
       self.current_state[key] = (command, new_report)
-    self.callback_action()
+    if not status_command:
+      self.callback_action()
 
 
   def generate_report(self):

+ 21 - 7
ambari-agent/src/main/python/ambari_agent/hostname.py

@@ -27,7 +27,14 @@ import traceback
 
 logger = logging.getLogger()
 
+cached_hostname = None
+cached_public_hostname = None
+
 def hostname():
+  global cached_hostname
+  if cached_hostname is not None:
+    return cached_hostname
+
   config = AmbariConfig.config
   try:
     scriptname = config.get('agent', 'hostname_script')
@@ -35,15 +42,20 @@ def hostname():
       osStat = subprocess.Popen([scriptname], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
       out, err = osStat.communicate()
       if (0 == osStat.returncode and 0 != len(out.strip())):
-        return out.strip()
+        cached_hostname = out.strip()
       else:
-        return socket.getfqdn()
+        cached_hostname = socket.getfqdn()
     except:
-      return socket.getfqdn()
+      cached_hostname = socket.getfqdn()
   except:
-    return socket.getfqdn()
+    cached_hostname = socket.getfqdn()
+  return cached_hostname
 
 def public_hostname():
+  global cached_public_hostname
+  if cached_public_hostname is not None:
+    return cached_public_hostname
+
   config = AmbariConfig.config
   out = ''
   err = ''
@@ -53,7 +65,8 @@ def public_hostname():
       output = subprocess.Popen([scriptname], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
       out, err = output.communicate()
       if (0 == output.returncode and 0 != len(out.strip())):
-        return out.strip()
+        cached_public_hostname = out.strip()
+        return cached_public_hostname
   except:
     #ignore for now. 
     trace_info = traceback.format_exc()
@@ -66,9 +79,10 @@ def public_hostname():
     handle = urllib2.urlopen('http://169.254.169.254/latest/meta-data/public-hostname', '', 2)
     str = handle.read()
     handle.close()
-    return str
+    cached_public_hostname = str
   except Exception, e:
-    return socket.getfqdn()
+    cached_public_hostname = socket.getfqdn()
+  return cached_public_hostname
 
 def main(argv=None):
   print hostname()

+ 22 - 0
ambari-agent/src/test/python/ambari_agent/TestCommandStatusDict.py

@@ -29,6 +29,28 @@ class TestCommandStatusDict(TestCase):
 
   logger = logging.getLogger()
 
+  def test_put_command_status(self):
+    execution_command = {
+      'commandType': 'EXECUTION_COMMAND',
+      'commandId': '1-1',
+      'clusterName': u'cc',
+      'exitCode': 777,
+      'role': u'DATANODE',
+      'roleCommand': u'INSTALL',
+      'serviceName': u'HDFS',
+      'taskId': 5
+    }
+    status_command = {
+      'componentName': 'DATANODE',
+      'commandType': 'STATUS_COMMAND',
+      }
+    callback_mock = MagicMock()
+    commandStatuses = CommandStatusDict(callback_action = callback_mock)
+    commandStatuses.put_command_status(status_command, None)
+    self.assertEqual(callback_mock.call_count, 0)
+    commandStatuses.put_command_status(execution_command, None)
+    self.assertEqual(callback_mock.call_count, 1)
+
   def test_put_and_generate(self):
     callback_mock = MagicMock()
     commandStatuses = CommandStatusDict(callback_action = callback_mock)

+ 20 - 1
ambari-agent/src/test/python/ambari_agent/TestHostname.py

@@ -19,21 +19,27 @@ limitations under the License.
 '''
 
 from unittest import TestCase
+import unittest
 import ambari_agent.hostname as hostname
 import ambari_agent.AmbariConfig as AmbariConfig
 import socket
 import tempfile
 import shutil
 import os, pprint, json,stat
+from mock.mock import patch
 
 class TestHostname(TestCase):
 
   def test_hostname(self):
+    hostname.cached_hostname = None
+    hostname.cached_public_hostname = None
     self.assertEquals(hostname.hostname(), socket.getfqdn(), 
                       "hostname should equal the socket-based hostname")
     pass
 
   def test_hostname_override(self):
+    hostname.cached_hostname = None
+    hostname.cached_public_hostname = None
     fd = tempfile.mkstemp(text=True)
     tmpname = fd[1]
     os.close(fd[0])
@@ -51,10 +57,11 @@ class TestHostname(TestCase):
     finally:
       os.remove(tmpname)
       config.remove_option('agent', 'hostname_script')
-
     pass
 
   def test_public_hostname_override(self):
+    hostname.cached_hostname = None
+    hostname.cached_public_hostname = None
     fd = tempfile.mkstemp(text=True)
     tmpname = fd[1]
     os.close(fd[0])
@@ -74,9 +81,21 @@ class TestHostname(TestCase):
     finally:
       os.remove(tmpname)
       config.remove_option('agent', 'public_hostname_script')
+    pass
 
+  @patch.object(socket, "getfqdn")
+  def test_caching(self, getfqdn_mock):
+    hostname.cached_hostname = None
+    hostname.cached_public_hostname = None
+    getfqdn_mock.side_effect = ["test.example.com", "test2.example.com'"]
+    self.assertEquals(hostname.hostname(), "test.example.com")
+    self.assertEquals(hostname.hostname(), "test.example.com")
+    self.assertEqual(getfqdn_mock.call_count, 1)
     pass
 
+if __name__ == "__main__":
+  unittest.main(verbosity=2)
+