ReqFuse.Steps.Fuse (ReqFuse v0.3.2)

View Source

Configure circuit-breaker via :fuse.

Summary

Functions

Attach the circuit-breaker :fuse step and configure the supported options.

(Hopefully) reasonable fuse defaults, based on the fuse docs: {{:standard, 10, 10000}, {:reset, 30000}}.

A default :fuse melt test.

Functions

attach(request, options)

@spec attach(
  Req.Request.t(),
  keyword()
) :: Req.Request.t()

Attach the circuit-breaker :fuse step and configure the supported options.

Only fuse-options are attached here; other options are dropped.

Fuse Options

  • :fuse_melt_func - A 1-arity function to determine if response should melt the fuse defaults to ReqFuse.Steps.Fuse.melt?/1
  • :fuse_mode - how to query the fuse, which has two values:
    • :sync - queries are serialized through the :fuse_server process (the default)
    • :async_dirty - queries check the fuse state directly, but may not account for recent melts or resets
  • :fuse_name - REQUIRED the name of the fuse to install
  • :fuse_opts The fuse strategy options (see fuse docs for reference) (order matters) defaults to {{:standard, 10, 10000}, {:reset, 30000}}. See defaults/0 for more information.
  • :fuse_verbose - If false, suppress Log output

See https://github.com/jlouis/fuse#tutorial for more information about the supported fuse strategies and their options.

Melt function

By default ReqFuse will send a melt message to your fuse server for any request where the status is over 500.

There are many other melt options. The melt_function must be a 1-arity function that evaluates the response. Pass the function reference in the :fuse_melt_func key as &Mod.fn/arity (or MFA notation).

Any melt function should be widely permissive of what it will evaluate.

In addition to a %Req.Response{} it could receive other error state messages from the underlying HTTP adapter libraries. For example:

  • {:error, %Mint.TransportError{reason: :econnrefused}}
  • {:error, %Mint.TransportError{reason: :timeout}}
  • {:error, %HTTPoison{}}
  • some_other_flavor_of_error

Example melt?/1 function

  def melt?(%Req.Response{} = response) do
    cond do
      response.status in [408, 429] -> true
      response.status >= 200 and response.status < 300 -> false
      response.status < 200 -> true
  end
  def melt?(%Req.Response{}),  do: false
  def melt?(error_response), do: true

Options Example

  [
    fuse_melt_func: &My.Fuse.CustoMod.my_melt_function/1,
    fuse_mode: :sync,
    fuse_name: My.Fuse.Name,
    fuse_opts: {{:standard, 1, 1000}, {:reset, 300}},
    fuse_verbose: true
  ]

defaults()

(Hopefully) reasonable fuse defaults, based on the fuse docs: {{:standard, 10, 10000}, {:reset, 30000}}.

  • fuse type
    • first tuple - Specify the fuse strategy (:standard or :fault_injection),
      • :standard, permit N (3) failures in M (10_000) milliseconds
        • {:standard, N, M}
        • {:standard, 3, 10_000}
      • :fault_injection, This fuse type sets up a fault injection scheme where the fuse fails at rate R (0.005), N (3) and M (10_000) work similar to :standard. e.g. {:fault_injection, 0.005, 3, 10_000}
        • {:fault_injection, R, N, M} (Inject one fault for 0.5% of requests, 3 failures in 10 seconds melts the fuse)
    • second tuple - Specify the recover period in milliseconds e.g. {:reset, 30_000} unmelt the fuse after 30 seconds.
      • {:reset, 30_000}

melt?(response)

@spec melt?(term()) :: boolean()

A default :fuse melt test.