September 7th 2016
ORGANIZERS
Charles King
Mike Groseclose
Omer Wazir
Chris Steinmeyer
A design pattern for detecting and encapsulating failures when invoking a remote system.
Prevents failures from recurring continuously.
Provides a mechanism for reintroducing the (potentially) faulty call back into the execution flow.
# apps/twitter/lib/twitter.ex start/2
:fuse.install(
"twitter_api_fuse",
{
{:standard, 1, 60_000},
#standard fuses (versus :fault_injection). Tolerate one failure/minute
{:reset, 900_000}
#reset the fuse in 15 minutes after it's :blown
}
)# apps/twitter/lib/twitter_search.ex
def search(query) do
case :fuse.ask("twitter_api_fuse", :sync) do # ask if our fuse is blown
:ok -> # if we are good...
ExTwitterBreaker.search(query) # wrapper around ExTwitter API
:blown -> # if we are blown...
get_tweet_cache(query) # get the results from cache.
end
end# apps/twitter/lib/twitter_search.ex
def search(query) do
case :fuse.ask("twitter_api_fuse", :sync) do # ask if our fuse is blown
:ok -> # if we are good...
ExTwitterBreaker.search(query) # wrapper around ExTwitter API
|> parse_tweets # parse the results
:blown -> # if we are blown...
get_tweet_cache(query) # get the results from cache.
end
defp parse_tweets({:ok, tweets}) do
update_tweet_cache(query)
Enum.map(tweets, fn(tweet) ->
result["text"]
end)
end
defp parse_tweets({:error, results}) do
:fuse.melt("twitter_api_fuse")
log_error(results)
get_tweet_cache(query)
end
endThanks to Mitchell Henke (@MitchellHenke) for the inspiration.
Chris Steinmeyer