Current section

Files

Jump to
defused lib defused.ex
Raw

lib/defused.ex

defmodule Defused do
@moduledoc """
Provides a `defused/3` macro similar to `Kernel#def/2` but that wraps all
calls to the provided function body in a call to the specified fuse that
will check and blow the fuse as needed.
"""
@doc """
## Examples
use Defused
defused :fuse_name, test(arg) do
case :rand.uniform() < 0.5 do
true -> {:ok, arg}
_ -> {:error, :boom}
end
end
"""
defmacro __using__(_env) do
quote do
import unquote(__MODULE__), only: [defused: 3]
# Otherwise dialyzer complains about some functions
# never matching :ok -> :ok
# TODO: remove once not needed anymore.
@dialyzer :no_match
end
end
defmacro defused(fuse, call, do: block) do
quote do
def unquote(call) do
case :fuse.ask(unquote(fuse), :sync) do
:ok -> case unquote(block) do
:ok -> :ok
{:ok, _} = res -> res
err ->
:fuse.melt(unquote(fuse))
err
end
:blown -> {:error, :unavailable}
end
end
end
end
end