active: true
derived: false
gherkin: |
  Feature: Blob Storage Base Interface
    Scenario: Ensuring consistent API across blob storage backends
      Given a concrete implementation of BlobStorageBase
      When methods like save, load, and delete are called
      Then they behave according to the abstract protocol and properly manage binary data
groups:
- STORE
header: |
  Blobストレージ抽象インターフェース
level: 2.24
links:
- ARCH004: gR_7wx5EpD_LA3s4JJTJmD1-WOKDjlo563zos3pn-aE=
normative: true
ref: ''
reviewed: YSF-YC12eAt883kOsRzMQJb95L6s4LNeqHYjDGMDg1I=
text: |
  ## インターフェース

  ```python
  class BlobStorageBase(ABC):
      @abstractmethod
      def save(self, key: str, data: ReadableBuffer) -> str: ...
      @abstractmethod
      def load(self, location: str) -> bytes: ...
      @abstractmethod
      def delete(self, location: str) -> None: ...
      @abstractmethod
      def list_keys(self) -> Iterator[str]: ...
      @abstractmethod
      def get_mtime(self, location: str) -> float: ...
  ```

  ## 振る舞い

  - **save**: データを永続化し、一意な識別子（パスやURI）を返す。
  - **load**: 識別子を基にバイトデータを復元する。
  - **delete**: 識別子を基にデータを削除する。存在しない場合は無視する（冪等）。
  - **list_keys**: メンテナンス用に、保存されている全オブジェクトの識別子を列挙する。
  - **get_mtime**: 最終更新時刻を POSIX タイムスタンプで返す。

  ## パラメータ詳細

  | パラメータ | 型 | 説明 |
  |---|---|---|
  | `key` | `str` | キャッシュキー（通常はハッシュ値） |
  | `data` | `bytes` / `memoryview` | シリアライズ済みバイナリ |
  | `location` | `str` | 実体へのポインタ（ファイルパス、S3 URI等） |

  ## エラーハンドリング

  - 実装クラスは、データの欠損やアクセス不可時に `CacheCorruptedError` を送出すべきである。

  ## エッジケース

  - **バイナリ互換**: `ReadableBuffer` を受け入れることで、`memoryview` 等を使用したゼロコピー書き込みを可能にする。

  ## 設計判断

  ローカルファイルやS3といった具体的なストレージ実装に依存しない抽象インターフェースを定義し、ユーザーが要件に合わせて独自の保存先を簡単に実装・注入できるようにするため。
