# `Stevedore.Server.Uploads`
[🔗](https://github.com/oshlabs/stevedore/blob/v0.2.0/lib/stevedore/server/uploads.ex#L1)

In-progress blob upload sessions for the registry server.

A registry blob upload is the one inherently stateful part of the `/v2` API: a client opens a
session, streams chunks (`PATCH`), then finalizes (`PUT`) with the expected digest. This
`GenServer` holds each session's accumulated bytes keyed by a UUID, and sweeps sessions that
have been idle longer than `:ttl` (so abandoned uploads don't leak memory).

Started by `Stevedore.Server`; not part of the weightless core.

Spec: [distribution-spec, blob uploads](https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks).

# `uuid`

```elixir
@type uuid() :: String.t()
```

# `append`

```elixir
@spec append(GenServer.server(), uuid(), iodata(), non_neg_integer() | nil) ::
  {:ok, non_neg_integer()} | {:error, :unknown_session | :bad_range}
```

Appends `chunk` to a session, returning the new total size.

`at` is the offset the chunk claims to start at (from a `Content-Range` header). When given, it
must equal the session's current size or the append is rejected with `{:error, :bad_range}` and
the session is left untouched — the distribution-spec requires chunks to arrive in order
(out-of-order or retried chunks yield `416`). Pass `nil` to append unconditionally (streamed
uploads with no range).

# `cancel`

```elixir
@spec cancel(GenServer.server(), uuid()) :: :ok
```

Cancels and discards a session.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `create`

```elixir
@spec create(GenServer.server()) :: {:ok, uuid()}
```

Opens a new upload session, returning its UUID.

# `finish`

```elixir
@spec finish(GenServer.server(), uuid()) ::
  {:ok, binary()} | {:error, :unknown_session}
```

Finalizes a session: removes it and returns the accumulated bytes.

# `size`

```elixir
@spec size(GenServer.server(), uuid()) ::
  {:ok, non_neg_integer()} | {:error, :unknown_session}
```

Current accumulated size of a session.

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Starts the session store. Options: `:name`, `:ttl` (ms).

# `sweep`

```elixir
@spec sweep(GenServer.server()) :: :ok
```

Removes sessions idle longer than the TTL. Runs periodically; exposed for tests.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
