ExStorageService.ObjectService (ex_storage_service v0.6.3)

Copy Markdown View Source

Coordinates object metadata with durable blob storage.

This is the object-domain boundary used by protocol adapters. It deliberately contains no Plug or S3 response logic. Blob and metadata implementations are injectable per call so fault and concurrency tests do not require mutable global configuration.

Summary

Functions

Commits metadata for a blob that is already durable in the local blob store.

Reuses a source object's immutable blob for a destination object.

Creates a delete marker or permanently deletes an explicit metadata version.

Returns object metadata and an efficient blob source.

Returns latest object metadata without opening its blob.

Returns latest or explicit-version metadata without opening its blob.

Opens a servable source for metadata already pinned by head/4.

Streams data into the blob store and makes the object visible atomically.

Stages a request body from a state-threaded reader and returns its final state.

Types

result()

@type result() :: %{
  :version_id => String.t() | nil,
  :metadata => map(),
  optional(:ready_blob) => term(),
  optional(:source) => term(),
  optional(:delete_marker) => boolean()
}

Functions

commit_existing_blob(bucket, key, ready, attributes, opts \\ [])

@spec commit_existing_blob(String.t(), String.t(), term(), map(), keyword()) ::
  {:ok, result()} | {:error, term()}

Commits metadata for a blob that is already durable in the local blob store.

Multipart completion uses this path after composing and committing the final blob. The caller retains the ready blob when metadata fails.

copy(source_bucket, source_key, destination_bucket, destination_key, opts \\ [])

@spec copy(String.t(), String.t(), String.t(), String.t(), keyword()) ::
  {:ok, result()} | {:error, term()}

Reuses a source object's immutable blob for a destination object.

The local implementation verifies and stats the source blob without loading it into an object-sized binary.

delete(bucket, key, version_id, opts \\ [])

@spec delete(String.t(), String.t(), String.t() | nil, keyword()) ::
  {:ok, %{version_id: String.t(), kind: :delete_marker | :deleted}}
  | {:error, term()}

Creates a delete marker or permanently deletes an explicit metadata version.

Blob bytes are never removed by this operation.

get(bucket, key, version_id, opts)

@spec get(String.t(), String.t(), String.t() | nil, keyword()) ::
  {:ok, result()} | {:error, term()}

Returns object metadata and an efficient blob source.

Delete markers are returned with source: nil; the protocol adapter decides how to express that marker. Missing latest and explicit versions are distinguished for adapters that support both error models.

head(bucket, key, opts \\ [])

@spec head(String.t(), String.t(), keyword()) :: {:ok, result()} | {:error, term()}

Returns latest object metadata without opening its blob.

head(bucket, key, version_id, opts)

@spec head(String.t(), String.t(), String.t() | nil, keyword()) ::
  {:ok, result()} | {:error, term()}

Returns latest or explicit-version metadata without opening its blob.

open_source(metadata, opts \\ [])

@spec open_source(
  map(),
  keyword()
) :: {:ok, term()} | {:error, term()}

Opens a servable source for metadata already pinned by head/4.

Protocol adapters use this after evaluating conditional and Range headers so the immutable version is not looked up a second time.

put(bucket, key, data, content_type, user_metadata, opts \\ [])

@spec put(
  String.t(),
  String.t(),
  Enumerable.t() | binary(),
  String.t(),
  map(),
  keyword()
) ::
  {:ok, result()} | {:error, term()}

Streams data into the blob store and makes the object visible atomically.

A metadata failure intentionally leaves the committed blob as a recoverable orphan. The object head is not made visible unless the versioning commit succeeds.

put_from_reader(bucket, key, reader, initial_state, content_type, user_metadata, opts \\ [])

@spec put_from_reader(
  String.t(),
  String.t(),
  (state -> ExStorageService.BlobStore.LocalCAS.reader_result(state)),
  state,
  String.t(),
  map(),
  keyword()
) :: {:ok, result(), state} | {:error, term(), state}
when state: term()

Stages a request body from a state-threaded reader and returns its final state.

Protocol adapters use this form when their body reader carries connection state that must also be used to send the response.