# `Sofa.Changes.Worker`
[🔗](https://github.com/skunkwerks/sofa/blob/0.5.1/lib/sofa/changes/worker.ex#L1)

One `_changes` request, run in its own process on behalf of a
`Sofa.Changes` follower.

The worker is linked to the follower and reports back with messages
tagged by the reference it was started with, so a follower can tell a
stale connection from the current one:

- `{ref, :data, chunk}` for each chunk of a continuous feed's body,
  sent only when the status is 200
- `{ref, :done, %Req.Response{}}` once the response ends. For a
  non-continuous feed the body is the decoded JSON batch, for a failed
  request it is the decoded error object
- `{ref, :error, exception}` when the request could not be made or the
  connection dropped, with a `Req.TransportError`

The worker then exits with reason `:normal`. Killing it closes the
connection, which is how a follower stops or restarts a feed.

# `message`

```elixir
@type message() ::
  {reference(), :data, binary()}
  | {reference(), :done, Req.Response.t()}
  | {reference(), :error, Exception.t()}
```

A message from the worker to its follower

# `request`

```elixir
@spec request(Sofa.t(), Sofa.Changes.Query.t()) :: Req.Request.t()
```

The Req request for `query`, without the streaming sink, exposed for inspection.

# `start_link`

```elixir
@spec start_link(owner :: pid(), reference(), Sofa.t(), Sofa.Changes.Query.t()) ::
  pid()
```

Spawns a linked worker that requests `/{db}/_changes` with `query` on
the database's Req client and reports to `owner` with `ref`.

---

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