170
173
return self._client.call(method, *args)
171
174
except errors.ErrorFromSmartServer, err:
172
self._translate_error(err)
175
# The first argument, if present, is always a path.
177
context = {'relpath': args[0]}
180
self._translate_error(err, **context)
174
182
def _call_with_body_bytes(self, method, args, body):
175
183
"""Call a method on the remote server with body bytes."""
177
185
return self._client.call_with_body_bytes(method, args, body)
178
186
except errors.ErrorFromSmartServer, err:
179
self._translate_error(err)
187
# The first argument, if present, is always a path.
189
context = {'relpath': args[0]}
192
self._translate_error(err, **context)
181
194
def has(self, relpath):
182
195
"""Indicate whether a remote file of the given name exists or not.
312
325
limit=self._max_readv_combine,
313
326
fudge_factor=self._bytes_to_read_before_seek))
316
result = self._client.call_with_body_readv_array(
317
('readv', self._remote_path(relpath),),
318
[(c.start, c.length) for c in coalesced])
319
resp, response_handler = result
320
except errors.ErrorFromSmartServer, err:
321
self._translate_error(err)
323
if resp[0] != 'readv':
324
# This should raise an exception
325
response_handler.cancel_read_body()
326
raise errors.UnexpectedSmartServerResponse(resp)
328
return self._handle_response(offsets, coalesced, response_handler)
330
def _handle_response(self, offsets, coalesced, response_handler):
331
# turn the list of offsets into a stack
328
# now that we've coallesced things, avoid making enormous requests
333
if c.length + cur_len > self._max_readv_bytes:
334
requests.append(cur_request)
338
cur_request.append(c)
341
requests.append(cur_request)
342
if 'hpss' in debug.debug_flags:
343
trace.mutter('%s.readv %s offsets => %s coalesced'
344
' => %s requests (%s)',
345
self.__class__.__name__, len(offsets), len(coalesced),
346
len(requests), sum(map(len, requests)))
347
# Cache the results, but only until they have been fulfilled
349
# turn the list of offsets into a single stack to iterate
332
350
offset_stack = iter(offsets)
333
cur_offset_and_size = offset_stack.next()
351
# using a list so it can be modified when passing down and coming back
352
next_offset = [offset_stack.next()]
353
for cur_request in requests:
355
result = self._client.call_with_body_readv_array(
356
('readv', self._remote_path(relpath),),
357
[(c.start, c.length) for c in cur_request])
358
resp, response_handler = result
359
except errors.ErrorFromSmartServer, err:
360
self._translate_error(err, relpath)
362
if resp[0] != 'readv':
363
# This should raise an exception
364
response_handler.cancel_read_body()
365
raise errors.UnexpectedSmartServerResponse(resp)
367
for res in self._handle_response(offset_stack, cur_request,
373
def _handle_response(self, offset_stack, coalesced, response_handler,
374
data_map, next_offset):
375
cur_offset_and_size = next_offset[0]
334
376
# FIXME: this should know how many bytes are needed, for clarity.
335
377
data = response_handler.read_body_bytes()
336
# Cache the results, but only until they have been fulfilled
339
379
for c_offset in coalesced:
340
380
if len(data) < c_offset.length: