Revision f3aebf6f lib/rpc/transport.py
b/lib/rpc/transport.py | ||
---|---|---|
27 | 27 |
|
28 | 28 |
import collections |
29 | 29 |
import errno |
30 |
import logging |
|
30 | 31 |
import socket |
31 | 32 |
import time |
32 | 33 |
|
... | ... | |
177 | 178 |
self.Send(msg) |
178 | 179 |
return self.Recv() |
179 | 180 |
|
181 |
@staticmethod |
|
182 |
def RetryOnBrokenPipe(fn, on_error): |
|
183 |
"""Calls a given function, retrying if it fails on the 'Broken pipe' IO |
|
184 |
exception. |
|
185 |
|
|
186 |
This allows to re-establish a broken connection and retry an IO operation. |
|
187 |
|
|
188 |
The function receives one an integer argument stating the current retry |
|
189 |
number, 0 being the first call, 1 being the retry. |
|
190 |
|
|
191 |
If any exception occurs, on_error is invoked first with the exception given |
|
192 |
as an argument. Then, if the exception is 'Broken pipe', the function call |
|
193 |
is retried once more. |
|
194 |
|
|
195 |
""" |
|
196 |
retries = 2 |
|
197 |
for try_no in range(0, retries): |
|
198 |
try: |
|
199 |
return fn(try_no) |
|
200 |
except socket.error, ex: |
|
201 |
on_error(ex) |
|
202 |
# we retry on "Broken pipe", unless it's the last try |
|
203 |
if try_no == retries - 1: |
|
204 |
raise |
|
205 |
elif not (isinstance(ex.args, tuple) and (ex[0] == errno.EPIPE)): |
|
206 |
raise |
|
207 |
except Exception, ex: |
|
208 |
on_error(ex) |
|
209 |
raise |
|
210 |
assert False # we should never get here |
|
211 |
|
|
180 | 212 |
def Close(self): |
181 | 213 |
"""Close the socket""" |
182 | 214 |
if self.socket is not None: |
Also available in: Unified diff