Current section

Files

Jump to
hardhat lib hardhat middleware regulator.ex
Raw

lib/hardhat/middleware/regulator.ex

defmodule Hardhat.Middleware.Regulator do
@moduledoc """
Limits concurrent requests to the server based on a [loss based dynamic limit algorithm](`Regulator.Limit.AIMD`).
Additively increases the concurrency limit when there are no errors and multiplicatively
decrements the limit when there are errors.
_This middleware is part of the default stack when giving the `strategy: :regulator` option to `use Hardhat`._
See also:
- Configuration options: `Hardhat.Defaults.regulator_opts/1`
- Determining what amounts to an error: `Hardhat.Defaults.should_regulate/1`
"""
@behaviour Tesla.Middleware
@impl Tesla.Middleware
def call(env = %Tesla.Env{}, next, opts) do
should_regulate = Keyword.fetch!(opts, :should_regulate)
regname = Module.concat(env.__module__, Regulator)
with true <- is_pid(Process.whereis(regname)),
{:ok, token} <- Regulator.ask(regname) do
result = Tesla.run(env, next)
if should_regulate.(result) do
Regulator.error(token)
else
Regulator.ok(token)
end
result
else
false ->
{:error, {:regulator_not_installed, regname}}
:dropped ->
{:error, :unavailable}
end
end
end