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