253
def _retry_get(self, relpath, ranges, exc_info):
254
"""A GET request have failed, let's retry with a simpler request."""
257
# The server does not gives us enough data or
258
# bogus-looking result, let's try again with
259
# a simpler request if possible.
260
if self._range_hint == 'multi':
261
self._range_hint = 'single'
262
mutter('Retry %s with single range request' % relpath)
264
elif self._range_hint == 'single':
265
self._range_hint = None
266
mutter('Retry %s without ranges' % relpath)
269
# Note that since the offsets and the ranges may not
270
# be in the same order we dont't try to calculate a
271
# restricted single range encompassing unprocessed
273
code, f = self._get(relpath, ranges)
274
return try_again, code, f
276
# We tried all the tricks, nothing worked
277
raise exc_info[0], exc_info[1], exc_info[2]
253
279
def readv(self, relpath, offsets):
254
280
"""Get parts of the file at the given relative path.
259
285
ranges = self.offsets_to_ranges(offsets)
260
286
mutter('http readv of %s collapsed %s offsets => %s',
261
287
relpath, len(offsets), ranges)
262
code, f = self._get(relpath, ranges)
293
code, f = self._get(relpath, ranges)
294
except (errors.InvalidRange, errors.ShortReadvError), e:
295
try_again, code, f = self._retry_get(relpath, ranges,
263
298
for start, size in offsets:
271
306
if len(data) != size:
272
307
raise errors.ShortReadvError(relpath, start, size,
273
308
actual=len(data))
274
except (errors.InvalidRange, errors.ShortReadvError):
275
# The server does not gives us enough data or
276
# bogus-looking result, let's try again with
277
# a simpler request if possible.
278
if self._range_hint == 'multi':
279
self._range_hint = 'single'
280
mutter('Retry %s with single range request' % relpath)
282
elif self._range_hint == 'single':
283
self._range_hint = None
284
mutter('Retry %s without ranges' % relpath)
287
# Note that since the offsets and the
288
# ranges may not be in the same order we
289
# dont't try to calculate a restricted
290
# single range encompassing unprocessed
291
# offsets. Note that we replace 'f' here
292
# and that it may need cleaning one day
293
# before being thrown that way.
294
code, f = self._get(relpath, ranges)
296
# We tried all the tricks, nothing worked
309
except (errors.InvalidRange, errors.ShortReadvError), e:
310
# Note that we replace 'f' here and that it
311
# may need cleaning one day before being
313
try_again, code, f = self._retry_get(relpath, ranges,
315
# After one or more tries, we get the data.
299
316
yield start, data