Ack both comments.

Interdiff:

diff --git a/lib/cmdlib/test.py b/lib/cmdlib/test.py
index f73a40d..2b10740 100644
--- a/lib/cmdlib/test.py
+++ b/lib/cmdlib/test.py
@@ -142,10 +142,11 @@ class LUTestDelay(NoHooksLU):
       sock.settimeout(self.op.duration)
       start = time.time()
       (conn, _) = sock.accept()
-    except socket.error, _:
+    except socket.timeout, _:
       # If we timed out, all is well
       return False
     finally:
+      # Destroys the original socket, but the new connection is still
usable
       socket_wrapper.Destroy()

     try:
@@ -160,7 +161,7 @@ class LUTestDelay(NoHooksLU):
       conn.settimeout(time_to_go)
       conn.recv(1)
       # pylint: enable=E1101
-    except socket.error, _:
+    except socket.timeout, _:
       # A second timeout can occur if no data is sent
       return False
     finally:



On Fri, Feb 21, 2014 at 3:51 PM, Petr Pudlák <[email protected]> wrote:

> I'd suggest to specifically check for a timeout exception, and re-raise
> any others so that if something bad happens, the situation gets properly
> logged (instead of acting as if a timeout occurred).
>
> Also I'd add a comment documenting that the socket is closed just after
> the first connection (and the communication with the connected client is
> magically kept open).
>
>
> On Tue, Feb 18, 2014 at 3:39 PM, Hrvoje Ribicic <[email protected]> wrote:
>
>> The gnt-debug delay command could be useful as a means of acquiring
>> locks for testing purposes. In practice, to be useful it should be
>> interruptible, otherwise we risk race conditions or long delays.
>>
>> This patch follows the examples of the move-instance command and the
>> gnt-debug test-jobqueue commands, and introduces a mechanism for
>> communicating with the delay command, allowing it to be interrupted
>> early.
>>
>> Signed-off-by: Hrvoje Ribicic <[email protected]>
>> ---
>>  lib/cmdlib/test.py | 68
>> ++++++++++++++++++++++++++++++++++++++++++++++++++----
>>  1 file changed, 64 insertions(+), 4 deletions(-)
>>
>> diff --git a/lib/cmdlib/test.py b/lib/cmdlib/test.py
>> index d623986..f73a40d 100644
>> --- a/lib/cmdlib/test.py
>> +++ b/lib/cmdlib/test.py
>> @@ -25,6 +25,7 @@ import logging
>>  import shutil
>>  import socket
>>  import tempfile
>> +import time
>>
>>  from ganeti import compat
>>  from ganeti import constants
>> @@ -127,8 +128,52 @@ class LUTestDelay(NoHooksLU):
>>      self.needed_locks = {}
>>      self.needed_locks[locking.LEVEL_NODE] = self.op.on_node_uuids
>>
>> -  def _TestDelay(self):
>> -    """Do the actual sleep.
>> +  def _InterruptibleDelay(self):
>> +    """Delays but provides the mechanisms necessary to interrupt the
>> delay as
>> +    needed.
>> +
>> +    """
>> +    socket_wrapper = TestSocketWrapper()
>> +    sock, path = socket_wrapper.Create()
>> +
>> +    self.Log(constants.ELOG_DELAY_TEST, (path,))
>> +
>> +    try:
>> +      sock.settimeout(self.op.duration)
>> +      start = time.time()
>> +      (conn, _) = sock.accept()
>> +    except socket.error, _:
>> +      # If we timed out, all is well
>> +      return False
>> +    finally:
>> +      socket_wrapper.Destroy()
>> +
>> +    try:
>> +      # Change to remaining time
>> +      time_to_go = self.op.duration - (time.time() - start)
>> +      self.Log(constants.ELOG_MESSAGE,
>> +               "Received connection, time to go is %d" % time_to_go)
>> +      if time_to_go < 0:
>> +        time_to_go = 0
>> +      # pylint: disable=E1101
>> +      # Instance of '_socketobject' has no ... member
>> +      conn.settimeout(time_to_go)
>> +      conn.recv(1)
>> +      # pylint: enable=E1101
>> +    except socket.error, _:
>> +      # A second timeout can occur if no data is sent
>> +      return False
>> +    finally:
>> +      conn.close()
>> +
>> +    self.Log(constants.ELOG_MESSAGE,
>> +             "Interrupted, time spent waiting: %d" % (time.time() -
>> start))
>> +
>> +    # Reaching this point means we were interrupted
>> +    return True
>> +
>> +  def _UninterruptibleDelay(self):
>> +    """Delays without allowing interruptions.
>>
>>      """
>>      if self.op.on_node_uuids:
>> @@ -140,17 +185,32 @@ class LUTestDelay(NoHooksLU):
>>        if not utils.TestDelay(self.op.duration)[0]:
>>          raise errors.OpExecError("Error during master delay test")
>>
>> +  def _TestDelay(self):
>> +    """Do the actual sleep.
>> +
>> +    @rtype: bool
>> +    @return: Whether the delay was interrupted
>> +
>> +    """
>> +    if self.op.interruptible:
>> +      return self._InterruptibleDelay()
>> +    else:
>> +      self._UninterruptibleDelay()
>> +      return False
>> +
>>    def Exec(self, feedback_fn):
>>      """Execute the test delay opcode, with the wanted repetitions.
>>
>>      """
>>      if self.op.repeat == 0:
>> -      self._TestDelay()
>> +      i = self._TestDelay()
>>      else:
>>        top_value = self.op.repeat - 1
>>        for i in range(self.op.repeat):
>>          self.LogInfo("Test delay iteration %d/%d", i, top_value)
>> -        self._TestDelay()
>> +        # Break in case of interruption
>> +        if self._TestDelay():
>> +          break
>>
>>
>>  class LUTestJqueue(NoHooksLU):
>> --
>> 1.9.0.rc1.175.g0b1dcb5
>>
>>
>

Reply via email to