Contexir.Dispatch (Contexir v0.2.0)

View Source

Internal module responsible for executing layered function calls.

Contexir.Dispatch builds and executes an execution plan composed of three ordered lists — the arounds, befores, and afters — that define how each active layer participates in a function call.

Execution Order

The dispatcher enforces this consistent call sequence for all active layers [A, B]:

A around
  B around
    A before
    B before
      primary
    B after
    A after
  B around end
A around end

Where each layer’s :around must explicitly call continue/3 to proceed to the next layer or the base function. If a layer omits that call, execution stops there — the layer effectively captures the call.

Contexir.Dispatch maintains no global state. All layer and context data are stored process-locally to ensure concurrency safety.

Summary

Functions

Dispatches a function call through all currently active layers.

Advances the current execution to the next layer or to the primary function.

Functions

call(module, fun, args)

Dispatches a function call through all currently active layers.

This is the entry point used internally by Contexir when a function defined with use Contexir is invoked. It builds an execution plan from the currently active layers and executes it according to Contexir’s layer order model (:around, :before, :after).

The module and fun identify the base function being called, and args represents the argument list (including the optional context map).

Example (internal)

Contexir.Dispatch.call(Account, :withdraw, [%{balance: 100}, 10, %{}])

continue(module, fun, args)

Advances the current execution to the next layer or to the primary function.

continue/3 must be called inside an :around partial to delegate control to the next layer in the chain. If there are no more :around layers left, it executes all :before and :after phases and finally calls the primary function.

The module and fun refer to the base function being refined, and args is the list of arguments to forward.

Example

defpartial Account.withdraw(acc, amt, ctx), mode: :around do
  IO.puts("Start")
  result = continue(Account, :withdraw, [acc, amt, ctx])
  IO.puts("End")
  result
end

If an :around partial does not call continue/3, execution halts at that layer and returns.

This function is used within Contexir’s layer DSL and should only be called from inside defpartial …, mode: :around blocks.