Skuld.Query.QueryBlock (skuld v0.3.0)

View Source

The query macro for applicative-do style automatic concurrent batching.

Analyses <- bindings in a do-block for data independence, then groups independent computations into concurrent fiber batches via FiberPool.fiber_await_all/1. Dependent bindings are sequenced with Comp.bind/2 as usual.

This gives users Haxl-style automatic batching without manual FiberPool.fiber + await_all! boilerplate.

Example

query do
  user   <- Users.get_user(id)
  recent <- Orders.get_recent()
  orders <- Orders.get_by_user(user.id)
  {user, recent, orders}
end

Here get_user and get_recent are independent and run concurrently, while get_by_user depends on user and runs after the first batch.

Syntax

  • var <- computation — effectful binding (auto-batched if independent)
  • var = expression — pure binding (participates in dependency analysis)
  • Last expression — auto-lifted to Comp.pure if not already a computation

Requirements

Requires a FiberPool handler to be installed.

Summary

Functions

Define a public function whose body is a query block.

Define a private function whose body is a query block.

Create a computation with automatic concurrent batching of independent bindings.

Functions

defquery(call_ast, clauses)

(macro)

Define a public function whose body is a query block.

Example

defquery user_with_orders(id) do
  user <- Users.get_user(id)
  recent <- Orders.get_recent()
  orders <- Orders.get_by_user(user.id)
  {user, recent, orders}
end

This is equivalent to:

def user_with_orders(id) do
  query do
    user <- Users.get_user(id)
    recent <- Orders.get_recent()
    orders <- Orders.get_by_user(user.id)
    {user, recent, orders}
  end
end

defqueryp(call_ast, clauses)

(macro)

Define a private function whose body is a query block.

Example

defqueryp internal_fetch(id) do
  user <- Users.get_user(id)
  orders <- Orders.get_by_user(user.id)
  {user, orders}
end

query(clauses)

(macro)

Create a computation with automatic concurrent batching of independent bindings.

See module documentation for details.