# `HTTP.AbortController`
[🔗](https://github.com/gsmlg-dev/http_fetch/blob/v0.21.17/apps/http_fetch/lib/http/abort_controller.ex#L1)

Request cancellation mechanism similar to the browser's AbortController API.

This module provides a way to abort in-flight HTTP requests using an Agent-based
controller. It's designed to work with the `HTTP.fetch/2` function via the
`:signal` option.

## How It Works

1. Create an AbortController before making the request
2. Pass the controller to `HTTP.fetch/2` via the `:signal` option
3. Call `abort/1` on the controller to cancel the request
4. The awaiting Promise will receive an error result

## Basic Usage

    # Create a controller
    controller = HTTP.AbortController.new()

    # Start a long-running request with the controller
    promise = HTTP.fetch("https://httpbin.org/delay/10",
      signal: controller,
      timeout: 20_000
    )

    # Abort the request (e.g., after 2 seconds)
    :timer.sleep(2000)
    HTTP.AbortController.abort(controller)

    # The awaited promise will return an error
    case HTTP.Promise.await(promise) do
      {:error, reason} ->
        IO.puts("Request was aborted: " <> inspect(reason))
      response ->
        IO.puts("Request completed before abort")
    end

## Advanced Usage

    # Abort from another process
    controller = HTTP.AbortController.new()

    # Start request in background
    Task.start(fn ->
      promise = HTTP.fetch("https://slow-api.example.com", signal: controller)
      result = HTTP.Promise.await(promise)
      IO.inspect(result)
    end)

    # Abort from main process after some condition
    :timer.sleep(1000)
    if some_condition?() do
      HTTP.AbortController.abort(controller)
    end

## Implementation Details

- Uses Elixir's `Agent` for state management
- Registers with a `Registry` for process tracking
- Sends an abort message to the socket owner process
- Thread-safe and can be called from any process
- Idempotent - calling `abort/1` multiple times is safe

## State Management

The controller maintains the following state:

- `request_id` - PID of the active socket owner process (set automatically)
- `signal_ref` - Unique reference for registry lookup
- `aborted` - Boolean flag indicating abort status

# `state`

```elixir
@type state() :: %{
  request_id: pid() | nil,
  signal_ref: reference(),
  aborted: boolean()
}
```

# `abort`

```elixir
@spec abort(pid()) :: :ok
```

Aborts the associated HTTP request.
Sends a stop signal if a request is active and not already aborted.

# `aborted?`

```elixir
@spec aborted?(pid()) :: boolean()
```

Checks if the controller has been aborted.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `new`

```elixir
@spec new() :: pid()
```

Creates a new AbortController instance.
Returns the PID of the agent, which acts as the controller reference.

# `set_request_id`

```elixir
@spec set_request_id(pid(), pid()) :: :ok
```

Sets the active request process for the given controller.
This links the controller to an active request.

# `start_link`

```elixir
@spec start_link(state()) :: {:ok, pid()}
```

Starts a new AbortController agent.
Returns `{:ok, pid}` of the agent.

---

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