View Source ExternalService.Gateway behaviour (external_service v1.1.4)
Defines a gateway to an external service.
ExternalService.Gateway
allows for defining module-based gateways to external services.
Instead of explicitly starting a fuse with its configuration and separately passing in retry
options on each call to the service, a module-based gateway allows one to specify default fuse
and retry options at the module level.
When a module uses the ExternalService.Gateway
module, an implementation of the
ExternalService.Gateway
behaviour will be generated using the fuse, retry, and rate-limit
options provided to the use ExternalService.Gateway
statement. See the documentation for the
various callbacks in this module for more details.
example
Example
defmodule MyApp.SomeService do
use ExternalService.Gateway,
fuse: [
# Tolerate 5 failures for every 1 second time window.
strategy: {:standard, 5, 10_000},
# Reset the fuse 5 seconds after it is blown.
refresh: 5_000
],
# Limit to 5 calls per second.
rate_limit: {5, :timer.seconds(1)},
retry: [
# Use linear backoff. Exponential backoff is also available.
backoff: {:linear, 100, 1},
# Stop retrying after 5 seconds.
expiry: 5_000
]
def call_the_service(params) do
external_call fn ->
# Call the service with params, then return the result or :retry.
case do_call(params) do
{:ok, result} -> {:ok, result}
{:error, reason} -> {:retry, reason}
end
end
end
end
initialization-and-configuration
Initialization and configuration
Gateways must be started (preferably under a supervisor) before being used.
To initialize a gateway with its default configuration, just add the gateway module to the top-level supervisor for your application:
children = [
MyApp.SomeService
]
Supervisor.start_link(children, strategy: :one_for_one)
It is also possible to override the default configuration for the gateway by passing options to the child specification that is passed to the supervisor. This can be useful for using different configuration in the test environment. For example:
some_service_config = Application.get_env(:my_app, :some_service, [])
children = [
{MyApp.SomeService, some_service_config}
]
Supervisor.start_link(children, strategy: :one_for_one)
Link to this section Summary
Callbacks
Invoked to call the given function using the retry options configured for the gateway.
Invoked to call the given function using custom retry options.
Like external_call/1
, but raises an exception if retries are exhausted or the fuse is blown.
Like external_call/2
, but raises an exception if retries are exhausted or the fuse is blown.
Asynchronous version of external_call/1
.
Asynchronous version of external_call/2
.
Parallel, streaming version of external_call/1
.
Parallel, streaming version of external_call/2
.
Parallel, streaming version of external_call/2
.
Link to this section Callbacks
@callback external_call(ExternalService.retriable_function()) :: ExternalService.error() | (function_result :: any())
Invoked to call the given function using the retry options configured for the gateway.
See ExternalService.call/3
for more information.
@callback external_call( ExternalService.RetryOptions.t(), ExternalService.retriable_function() ) :: ExternalService.error() | (function_result :: any())
Invoked to call the given function using custom retry options.
See ExternalService.call/3
for more information.
@callback external_call!(ExternalService.retriable_function()) :: function_result :: any() | no_return()
Like external_call/1
, but raises an exception if retries are exhausted or the fuse is blown.
See ExternalService.call!/3
for more information.
@callback external_call!( ExternalService.RetryOptions.t(), ExternalService.retriable_function() ) :: function_result :: any() | no_return()
Like external_call/2
, but raises an exception if retries are exhausted or the fuse is blown.
See ExternalService.call!/3
for more information.
@callback external_call_async(ExternalService.retriable_function()) :: Task.t()
Asynchronous version of external_call/1
.
Returns a Task
that may be used to retrieve the result of the async call.
See ExternalService.call_async
for more information.
@callback external_call_async( ExternalService.RetryOptions.t(), ExternalService.retriable_function() ) :: Task.t()
Asynchronous version of external_call/2
.
Returns a Task
that may be used to retrieve the result of the async call.
See ExternalService.call_async
for more information.
@callback external_call_async_stream( Enumerable.t(), (any() -> ExternalService.retriable_function_result()) ) :: Enumerable.t()
Parallel, streaming version of external_call/1
.
See ExternalService.call_async_stream/5
for more information.
@callback external_call_async_stream( Enumerable.t(), ExternalService.RetryOptions.t() | (async_opts :: list()), (any() -> ExternalService.retriable_function_result()) ) :: Enumerable.t()
Parallel, streaming version of external_call/2
.
See ExternalService.call_async_stream/5
for more information.
@callback external_call_async_stream( Enumerable.t(), ExternalService.RetryOptions.t(), async_opts :: list(), (any() -> ExternalService.retriable_function_result()) ) :: Enumerable.t()
Parallel, streaming version of external_call/2
.
See ExternalService.call_async_stream/5
for more information.