Reqord.CassetteWriter (reqord v0.4.0)

View Source

GenServer for asynchronously writing cassette entries with timestamp-based ordering.

The CassetteWriter is a core component of Reqord's new architecture that solves concurrent request ordering issues. It provides:

  • Async writes: Non-blocking cassette writes during test execution
  • Timestamp sorting: Automatic chronological ordering of entries before writing
  • Intelligent batching: Configurable batch sizes and timeouts for optimal I/O
  • Crash recovery: Supervised GenServer with automatic restart
  • Backpressure handling: Graceful handling of high-volume recording scenarios

How It Works

When a request is recorded, the writer:

  1. Adds the entry to a pending batch for that cassette
  2. Starts/resets a batch timer
  3. When batch size is reached OR timer expires:
    • Sorts all pending entries by recorded_at timestamp
    • Writes the sorted batch to the storage backend
    • Clears pending entries for that cassette

This ensures that even if concurrent requests complete out of order, they are written to cassettes in chronological order based on when they were initiated.

Configuration

The writer can be configured via application config:

config :reqord,
  writer_config: %{
    batch_size: 10,        # Max entries per batch
    batch_timeout: 100,    # Max wait time in milliseconds
  }

Supervision

The CassetteWriter is automatically started by the Reqord.Application supervisor and will be restarted if it crashes. All pending writes are flushed on termination.

Summary

Functions

Returns a specification to start this module under a supervisor.

Flushes all pending writes for all cassettes.

Immediately flushes all pending writes for a specific cassette.

Replaces an entire cassette with accumulated entries for :all mode. This ensures cassettes are only replaced when we have the complete new data.

Starts the CassetteWriter GenServer.

Asynchronously writes an entry to a cassette.

Functions

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

flush_all()

Flushes all pending writes for all cassettes.

flush_cassette(cassette_path)

Immediately flushes all pending writes for a specific cassette.

replace_cassette_for_all_mode(cassette_path)

Replaces an entire cassette with accumulated entries for :all mode. This ensures cassettes are only replaced when we have the complete new data.

start_link(opts \\ [])

Starts the CassetteWriter GenServer.

write_entry(cassette_path, entry)

Asynchronously writes an entry to a cassette.