Skuld.Effects.DB.Batch (skuld v0.2.3)

View Source

Batched database read effect using FiberPool.

This module implements batchable read operations using the FiberPool's batching infrastructure. Multiple concurrent fetch operations for the same schema are automatically batched into a single query.

Usage

To use batched reads, you need to:

  1. Install batch executors using DB.Batch.with_executors/1 or BatchExecutor.with_executor/3
  2. Run the computation in a FiberPool

Example

alias Skuld.Effects.DB
alias Skuld.Effects.FiberPool
alias Skuld.Effects.Reader

comp do
  # Submit multiple fibers that each fetch a user
  h1 <- FiberPool.fiber(DB.Batch.fetch(User, 1))
  h2 <- FiberPool.fiber(DB.Batch.fetch(User, 2))
  h3 <- FiberPool.fiber(DB.Batch.fetch(User, 3))

  # Await all - the DB.Batch.fetch calls will be batched into one query
  FiberPool.await_all!([h1, h2, h3])
end
|> DB.Batch.with_executors()
|> Reader.with_handler(:repo, tag: :repo)
|> FiberPool.with_handler()
|> FiberPool.run()

How It Works

  1. Each DB.Batch.fetch call returns an InternalSuspend with a Batch payload
  2. The FiberPool scheduler collects batch-suspended fibers
  3. When the run queue is empty, the scheduler groups suspensions by batch_key
  4. For each group, the registered executor runs a single batched query
  5. Results are distributed back to the waiting fibers

Summary

Functions

Fetch a single record by ID.

Fetch all records matching a filter.

Install standard DB batch executors for a computation.

Install a custom fetch executor.

Functions

fetch(schema, id)

@spec fetch(module(), term()) :: Skuld.Comp.Types.computation()

Fetch a single record by ID.

The fetch operation suspends the current fiber and waits for batch execution. Multiple fetch operations for the same schema are automatically batched.

Returns nil if the record is not found.

fetch_all(schema, filter_key, filter_value)

@spec fetch_all(module(), atom(), term()) :: Skuld.Comp.Types.computation()

Fetch all records matching a filter.

Multiple fetch_all operations with the same schema and filter_key are automatically batched.

Returns a list of matching records.

with_executors(comp)

Install standard DB batch executors for a computation.

This installs executors for:

  • {:db_fetch, :_} - Batched single-record fetches
  • {:db_fetch_all, :_, :_} - Batched multi-record fetches

The executors use :repo from Reader to perform queries.

Example

comp do
  # ... DB.Batch operations ...
end
|> DB.Batch.with_executors()
|> Reader.with_handler(MyApp.Repo, tag: :repo)
|> FiberPool.run()

with_fetch_all_executor(comp, schema, filter_key, executor)

@spec with_fetch_all_executor(
  Skuld.Comp.Types.computation(),
  module(),
  atom(),
  Skuld.Fiber.FiberPool.BatchExecutor.executor()
) :: Skuld.Comp.Types.computation()

Install a custom fetch_all executor.

with_fetch_executor(comp, schema, executor)

@spec with_fetch_executor(
  Skuld.Comp.Types.computation(),
  module(),
  Skuld.Fiber.FiberPool.BatchExecutor.executor()
) :: Skuld.Comp.Types.computation()

Install a custom fetch executor.

Useful for testing with mock data.