Skip to main content

CHANGELOG.md

# Changelog

## 0.2.9

### Changed

- `split_headers` now calls `binary:split(Headers, Rn, [global])`
  instead of the hand-rolled recursive `binary_split_global/2`.
  The native BIF skips the function-call-per-token overhead and
  is generally faster on the hot path (header split fires once
  per response). The hand-rolled helper is gone.

### Plan-time notes

- B6's "chunked decoding accumulates iolist instead of flattening
  per chunk" recommendation was checked on inspection and not
  acted on: `parse_chunks/3` already accumulates chunk bodies in
  a list (`[Body | Acc]`) and calls `iolist_to_binary` exactly
  once at the end. The plan's claim of "iolist_to_binary per
  chunk" was incorrect.

## 0.2.8

### Added

- `error_reason/0` is now a documented sum type, exported alongside
  `error/0`. It enumerates the eight atoms that buoy can put in the
  second slot of `{error, _}`:

  - `pool_not_started`, `buoy_not_started`, `pool_already_started`,
    `invalid_url` (buoy-level)
  - `invalid_headers`, `invalid_chunk_size` (HTTP parser errors)
  - `no_server`, `shackle_not_started`, `timeout` (shackle errors
    that propagate through buoy)

  `error/0` itself stays loose (`{error, term()}`) — tightening it
  to a closed sum produces dialyzer false positives in
  `buoy_client:responses/5`, where the `{error, not_enough_data}`
  buffering pattern is semantically required at runtime but
  unreachable from dialyzer's flow analysis. The documented
  `error_reason/0` covers the documentation half of the A2
  standardization without the analyzer cost.

### Exported types

  - `error/0`
  - `error_reason/0`

## 0.2.7

### Added

- Two telemetry events at the request boundary:

  | Event | Measurements | Metadata |
  |---|---|---|
  | `[buoy, request, sent]`  | `count => 1` | `method, host, async` |
  | `[buoy, request, error]` | `count => 1` | `method, host, reason` |

  `sent` fires when the request hits shackle for dispatch (sync and
  async paths both); `error` fires when the pool lookup fails (e.g.
  `pool_not_started`). Attach handlers via `telemetry:attach/4`.

  Per-request lifecycle (queue / send / receive) remains observable
  via shackle's own telemetry — buoy's events surface the buoy-level
  routing decision without duplicating that work.

- `telemetry` (1.4.2) is now a direct dependency (was already
  transitively present via shackle).

- `vsn` in `buoy.app.src` is now an explicit string (`"0.2.7"`) — was
  `git`, which only works when built from a checkout.

No source or API changes.

## 0.2.6

Infrastructure refresh: dep bumps + docs migration.

### Changed

- Bumped `shackle` from git ref `0.6.19` to hex `0.7.1` -- fixes the
  OTP 27+ build break that buoy inherited transitively (old shackle
  versions pulled `granderl 0.1.5` from hex, broken on modern OTP).
- Bumped `foil` from git ref `0.1.2` to hex `0.1.4`.
- CI matrix bumped from OTP 21-26 to OTP 25-28.
- `cowboy` test dep bumped from git ref `2.10.0` to hex `2.12.0`.
  (Newer cowboy releases use a cowlib version constraint that the
  rebar3 bundled in the OTP 25 container image can't parse;
  pinning to 2.12.0 keeps the OTP 25 test row green.)
- `fprofx` test dep moved from `ransomr/fprofx` to `lpgauth/fprofx`
  (`otp_19` branch), matching the rest of the ecosystem.
- Documentation migrated from `edown` to `rebar3_ex_doc`. Generated
  `doc/` directory removed.

No source or API changes.