[PATCH] Machine: fix timeout handling

olichtne at redhat.com olichtne at redhat.com
Mon May 27 13:53:32 UTC 2013


From: Ondrej Lichtner <olichtne at redhat.com>

Before the reimplementation of controller <-> slave communication we
used socket timeouts to implement command timeouts. However since now we
are using select calls over all our connections this doesn't work
anymore. Furthermore using select timeout isn't very usefull as we are
continually recieving log messages from other slaves.

This commit implements the timeout mechanism by using the signal.alarm
call. The handler function raises an Exception that indicates a timeout
of a command.

Signed-off-by: Ondrej Lichtner <olichtne at redhat.com>
---
 lnst/Controller/Machine.py | 25 ++++++++++++++-----------
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/lnst/Controller/Machine.py b/lnst/Controller/Machine.py
index d8162fc..006a5a0 100644
--- a/lnst/Controller/Machine.py
+++ b/lnst/Controller/Machine.py
@@ -17,6 +17,7 @@ import os
 import re
 import pickle
 import tempfile
+import signal
 from time import sleep
 from xmlrpclib import Binary
 from pprint import pprint, pformat
@@ -158,22 +159,24 @@ class Machine(object):
 
         self._configured = False
 
+    def _timeout_handler(self, signum, frame):
+        msg = "RPC connection to machine %s timed out" % self.get_id()
+        raise MachineError(msg)
+
     def run_command(self, command):
         """ Run a command on the machine """
 
+        prev_handler = signal.signal(signal.SIGALRM, self._timeout_handler)
+
         if "timeout" in command:
             timeout = command["timeout"]
-            logging.debug("Setting socket timeout to \"%d\"", timeout)
-            socket.setdefaulttimeout(timeout)
-        try:
-            cmd_res = self._rpc_call("run_command", command)
-        except socket.timeout:
-            msg = "RPC connection to machine %s timed out" % self.get_id()
-            raise Machine(msg)
-        finally:
-            if "timeout" in command:
-                logging.debug("Setting socket timeout to default value")
-                socket.setdefaulttimeout(None)
+            logging.debug("Setting timeout to \"%d\"", timeout)
+            signal.alarm(timeout)
+
+        cmd_res = self._rpc_call("run_command", command)
+
+        signal.alarm(0)
+        signal.signal(signal.SIGALRM, prev_handler)
 
         return cmd_res
 
-- 
1.8.1.4



More information about the LNST-developers mailing list