Skip to content

Commit

Permalink
Re-reaise IncompleteReadError as MaybeRecoverableError
Browse files Browse the repository at this point in the history
S3 and Azure can throw IncompleteReadError when the TCP session was
disrupted. However, current implementation does not re-reaise it as
MaybeRecoverableError. As a result, programs like pghoard will give up
basebackup download.

This is more likely to affect large (2~4 TiB) databases, because large
database takes longer to download base backup and more likely to
encounter at least one IncompleteReadError.

This commit re-reaise IncompleteReadError as MaybeRecoverableError, so
pghoard can retry on an object without starting over.
  • Loading branch information
orange-kao committed Oct 28, 2024
1 parent 47d3ed7 commit 95c329e
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 4 deletions.
5 changes: 4 additions & 1 deletion rohmu/object_storage/azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@

from __future__ import annotations

from azure.core.exceptions import HttpResponseError, ResourceExistsError
from azure.core.exceptions import HttpResponseError, IncompleteReadError, ResourceExistsError
from azure.storage.blob import BlobServiceClient, ContentSettings
from rohmu.common.statsd import StatsdConfig
from rohmu.errors import (
FileNotFoundFromStorageError,
InvalidConfigurationError,
MaybeRecoverableError,
StorageError,
TransferObjectStoreInitializationError,
TransferObjectStoreMissingError,
Expand Down Expand Up @@ -379,6 +380,8 @@ def get_contents_to_fileobj(
self._stream_blob(path, fileobj_to_store_to, byte_range, progress_callback)
except azure.core.exceptions.ResourceNotFoundError as ex:
raise FileNotFoundFromStorageError(path) from ex
except IncompleteReadError as ex:
raise MaybeRecoverableError("IncompleteReadError") from ex

if progress_callback:
progress_callback(1, 1)
Expand Down
3 changes: 1 addition & 2 deletions rohmu/object_storage/google.py
Original file line number Diff line number Diff line change
Expand Up @@ -889,8 +889,7 @@ def next_chunk(self) -> tuple[MediaDownloadProgress, bool]:
headers = self._headers.copy()
chunk_start = self._num_bytes_downloaded + self._start_position
chunk_end = chunk_start + self._chunksize - 1
if self._end_position < chunk_end:
chunk_end = self._end_position
chunk_end = min(self._end_position, chunk_end)
headers["range"] = f"bytes={chunk_start}-{chunk_end}"
resp, content = self._http.request(self._uri, "GET", headers=headers)

Expand Down
7 changes: 6 additions & 1 deletion rohmu/object_storage/s3.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
ConcurrentUploadError,
FileNotFoundFromStorageError,
InvalidConfigurationError,
MaybeRecoverableError,
StorageError,
TransferObjectStoreInitializationError,
TransferObjectStoreMissingError,
Expand Down Expand Up @@ -424,7 +425,11 @@ def _read_object_to_fileobj(
while data_read < body_length:
read_amount = body_length - data_read
read_amount = min(read_amount, READ_BLOCK_SIZE)
data = streaming_body.read(amt=read_amount)
try:
data = streaming_body.read(amt=read_amount)
except botocore.exceptions.IncompleteReadError as ex:
raise MaybeRecoverableError("botocore.exceptions.IncompleteReadError") from ex

fileobj.write(data)
data_read += len(data)
if cb:
Expand Down

0 comments on commit 95c329e

Please sign in to comment.