Defines the contract for EasyRpc middleware plugs.
A plug sits in a pipeline and can inspect, modify, or short-circuit an RPC call. Each plug receives three arguments:
context— an%EasyRpc.Context{}flowing through the pipelineopts— arbitrary options configured when the plug is addednext— a function that calls the rest of the pipeline
Return value
Every plug must return an %EasyRpc.Context{}. The simplest
implementation just delegates to next:
def call(ctx, _opts, next), do: next.(ctx)To short-circuit (bypass downstream plugs), set ctx.halted = true:
def call(ctx, _opts, _next) do
cached = Cache.get(cache_key(ctx))
if cached, do: %{ctx | result: cached, halted: true}, else: next.(ctx)
endTo wrap (do work before and after downstream plugs):
def call(ctx, opts, next) do
start = System.monotonic_time()
result = next.(ctx)
duration = System.monotonic_time() - start
:telemetry.execute([:easy_rpc, :call], %{duration: duration}, %{})
result
endExample — cache plug
defmodule MyCachePlug do
@behaviour EasyRpc.Plug
def call(ctx, _opts, next) do
key = cache_key(ctx)
case Cachex.get(:rpc_cache, key) do
{:ok, nil} ->
result = next.(ctx)
if result.result, do: Cachex.put(:rpc_cache, key, result.result)
result
{:ok, cached} ->
%{ctx | result: cached, halted: true}
end
end
defp cache_key(ctx), do: {ctx.config.module, ctx.function, ctx.args}
end
Summary
Callbacks
Invokes the plug.
Callbacks
@callback call(context :: EasyRpc.Context.t(), opts :: term(), next :: function()) :: EasyRpc.Context.t()
Invokes the plug.
Receives the current %EasyRpc.Context{}, the plug options, and a next
function that runs the remainder of the pipeline. Must return a
(possibly modified) %EasyRpc.Context{}.