Skuld.PageMachine (skuld_concurrency v0.47.0)

View Source

LiveView integration for FiberPool.Server — a multi-fiber page machine with bidirectional message passing.

Usage

use Skuld.PageMachine,
  tag: :checkout,
  on_yield: &handle_yield/2,
  on_complete: &handle_complete/2

Multi-spindle mode

For pages with concurrent spindles, use /3 callbacks:

on_yield: &handle_yield/3

defp handle_yield(:cart, status, socket), do: ...
defp handle_yield(:checkout, step, socket), do: ...

Event routing

Events route to spindles by name:

def_pipe_event "search", into: :products, before: &start_spinner/1
def_pipe_event "buy", into: :products

Typed contract

For compile-time validation of the entire spindle ↔ LiveView contract, define a contract module with use Skuld.PageMachine.Contract and pass it via the :contract option:

defmodule MyApp.StoreContract do
  use Skuld.PageMachine.Contract

  defevent "search", SearchEvent, params: [query: String.t()]
  defevent "buy", BuyEvent, params: [product: Product.t()]

  defyield :browsing
  defyield :results, params: [products: [Product.t()], total: integer()]
  defyield :checkout, :shipping
end

use Skuld.PageMachine,
  contract: MyApp.StoreContract,
  on_yield: &handle_yield/3

The contract auto-generates handle_event/3 clauses for each event, so manual def_pipe_event declarations are unnecessary (though still available for ad-hoc additions).

Summary

Functions

Cancel a running page machine and all its spindles.

The default assign key used to look up the PageMachine pid from socket.assigns.

The default PageMachine tag.

Resume a yielded spindle with a value.

Start a page machine in a separate FiberPool.Server process.

Functions

cancel(pid)

Cancel a running page machine and all its spindles.

def_pipe_event(event, opts \\ [])

(macro)

def_pipe_event(event, pattern, opts)

(macro)

default_assign_key()

The default assign key used to look up the PageMachine pid from socket.assigns.

default_tag()

The default PageMachine tag.

resume(pid, fiber_key, value)

Resume a yielded spindle with a value.

run(fibers, fibers \\ [])

Start a page machine in a separate FiberPool.Server process.

Takes a keyword list of {spindle_key, computation} pairs:

{:ok, pid} = PageMachine.run(products: ProductBrowserSpindle.run(%{}))

When a socket is passed as the first argument, the pid is stored automatically in socket.assigns under the default assign key (Skuld.PageMachine.DefaultAssign):

socket =
  PageMachine.run(socket, products: ProductBrowserSpindle.run(%{}))

Multiple spindles can be started at once:

PageMachine.run(products: product_comp, checkout: checkout_comp)

Options

  • :tag — the PMC tag for message routing. Defaults to Skuld.PageMachine.Default. Only needed for multi-PMC pages.