Revision 7d444d59 lib/utils/algo.py

b/lib/utils/algo.py
23 23
"""
24 24

  
25 25
import re
26
import time
26 27

  
27 28

  
28 29
_SORTER_RE = re.compile("^%s(.*)$" % (8 * "(\D+|\d+)?"))
......
111 112
    keyfunc = lambda value: _NiceSortKey(key(value))
112 113

  
113 114
  return sorted(values, key=keyfunc)
115

  
116

  
117
class RunningTimeout(object):
118
  """Class to calculate remaining timeout when doing several operations.
119

  
120
  """
121
  __slots__ = [
122
    "_allow_negative",
123
    "_start_time",
124
    "_time_fn",
125
    "_timeout",
126
    ]
127

  
128
  def __init__(self, timeout, allow_negative, _time_fn=time.time):
129
    """Initializes this class.
130

  
131
    @type timeout: float
132
    @param timeout: Timeout duration
133
    @type allow_negative: bool
134
    @param allow_negative: Whether to return values below zero
135
    @param _time_fn: Time function for unittests
136

  
137
    """
138
    object.__init__(self)
139

  
140
    if timeout is not None and timeout < 0.0:
141
      raise ValueError("Timeout must not be negative")
142

  
143
    self._timeout = timeout
144
    self._allow_negative = allow_negative
145
    self._time_fn = _time_fn
146

  
147
    self._start_time = None
148

  
149
  def Remaining(self):
150
    """Returns the remaining timeout.
151

  
152
    """
153
    if self._timeout is None:
154
      return None
155

  
156
    # Get start time on first calculation
157
    if self._start_time is None:
158
      self._start_time = self._time_fn()
159

  
160
    # Calculate remaining time
161
    remaining_timeout = self._start_time + self._timeout - self._time_fn()
162

  
163
    if not self._allow_negative:
164
      # Ensure timeout is always >= 0
165
      return max(0.0, remaining_timeout)
166

  
167
    return remaining_timeout

Also available in: Unified diff