Page MenuHomePhorge

No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None
diff --git a/config/config.exs b/config/config.exs
index e818281..c91e462 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -1,13 +1,17 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config
config :tesla, adapter: :httpc
config :logger, :console,
level: :debug,
format: "$date $time [$level] $metadata$message\n"
if Mix.env == :test do
config :httparrot, http_port: 8888
+
+ config :sasl,
+ errlog_type: :error,
+ sasl_error_logger: false
end
diff --git a/lib/tesla/middleware/fuse.ex b/lib/tesla/middleware/fuse.ex
new file mode 100644
index 0000000..668bbe9
--- /dev/null
+++ b/lib/tesla/middleware/fuse.ex
@@ -0,0 +1,52 @@
+defmodule Tesla.Middleware.Fuse do
+ @moduledoc """
+ Fuse (https://github.com/jlouis/fuse) middleware
+
+ Remember to add `{:fuse, "~> 2.4"}` to dependencies
+ and `:fuse` to applications in `mix.exs`
+
+ Example
+ defmodule Myclient do
+ use Tesla
+
+ plug Tesla.Middleware.Fuse, opts: {{:standard, 2, 10_000}, {:reset, 60_000}}
+ end
+
+ Options:
+ - `:name` - fuse name (defaults to module name)
+ - `:opts` - fuse options (see fuse docs for reference)
+ """
+
+
+
+ # options borrowed from http://blog.rokkincat.com/circuit-breakers-in-elixir/
+ # most probably not valid for your use case
+ @defaults {{:standard, 2, 10_000}, {:reset, 60_000}}
+
+ def call(env, next, opts) do
+ opts = opts || []
+ name = Keyword.get(opts, :name, env.__module__)
+
+ case :fuse.ask(name, :sync) do
+ :ok ->
+ run(env, next, name)
+
+ :blown ->
+ {:error, :unavailable}
+
+ {:error, :not_found} ->
+ :fuse.install(name, Keyword.get(opts, :opts, @defaults))
+ run(env, next, name)
+ end
+ end
+
+ defp run(env, next, name) do
+ try do
+ Tesla.run(env, next)
+ rescue
+ error ->
+ :fuse.melt(name)
+ {:error, :unavailable}
+ end
+ end
+end
diff --git a/mix.exs b/mix.exs
index 88ae244..fcc72c0 100644
--- a/mix.exs
+++ b/mix.exs
@@ -1,62 +1,64 @@
defmodule Tesla.Mixfile do
use Mix.Project
def project do
[
app: :tesla,
version: "0.5.2",
description: description,
package: package,
source_url: "https://github.com/teamon/tesla",
elixir: "~> 1.3",
deps: deps,
test_coverage: [tool: ExCoveralls],
dialyzer: [
plt_add_apps: [:inets],
plt_add_deps: :project
],
docs: [extras: ["README.md"]]
]
end
# Configuration for the OTP application
#
# Type `mix help compile.app` for more information
def application do
[applications: applications(Mix.env)]
end
def applications(:test), do: applications(:dev) ++ [:httparrot]
def applications(_), do: [:logger]
defp description do
"HTTP client library, with support for middleware and multiple adapters."
end
defp package do
[
maintainers: ["Tymon Tobolski"],
licenses: ["MIT"],
links: %{"GitHub" => "https://github.com/teamon/tesla"}
]
end
defp deps do
[
# http clients
{:ibrowse, "~> 4.2", optional: true},
{:hackney, "~> 1.6.0", optional: true},
# json parsers
{:exjsx, ">= 0.1.0", optional: true},
{:poison, ">= 1.0.0", optional: true},
+ {:fuse, "~> 2.4", optional: true},
+
# testing & docs
{:httparrot, "~> 0.4.1", only: :test},
{:excoveralls, "~> 0.5", only: :test},
{:ex_doc, "~> 0.13.0", only: :dev},
{:mix_test_watch, "~> 0.2.6", only: :dev},
{:dialyxir, "~> 0.3.5", only: :dev}
]
end
end
diff --git a/mix.lock b/mix.lock
index 76d2219..581549a 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,20 +1,21 @@
%{"certifi": {:hex, :certifi, "0.4.0", "a7966efb868b179023618d29a407548f70c52466bf1849b9e8ebd0e34b7ea11f", [:rebar3], []},
"cowboy": {:hex, :cowboy, "1.0.4", "a324a8df9f2316c833a470d918aaf73ae894278b8aa6226ce7a9bf699388f878", [:rebar, :make], [{:cowlib, "~> 1.0.0", [hex: :cowlib, optional: false]}, {:ranch, "~> 1.0", [hex: :ranch, optional: false]}]},
"cowlib": {:hex, :cowlib, "1.0.2", "9d769a1d062c9c3ac753096f868ca121e2730b9a377de23dec0f7e08b1df84ee", [:make], []},
"dialyxir": {:hex, :dialyxir, "0.3.5", "eaba092549e044c76f83165978979f60110dc58dd5b92fd952bf2312f64e9b14", [:mix], []},
"earmark": {:hex, :earmark, "1.0.1", "2c2cd903bfdc3de3f189bd9a8d4569a075b88a8981ded9a0d95672f6e2b63141", [:mix], []},
"ex_doc": {:hex, :ex_doc, "0.13.0", "aa2f8fe4c6136a2f7cfc0a7e06805f82530e91df00e2bff4b4362002b43ada65", [:mix], [{:earmark, "~> 1.0", [hex: :earmark, optional: false]}]},
"excoveralls": {:hex, :excoveralls, "0.5.6", "35a903f6f78619ee7f951448dddfbef094b3a0d8581657afaf66465bc930468e", [:mix], [{:exjsx, "~> 3.0", [hex: :exjsx, optional: false]}, {:hackney, ">= 0.12.0", [hex: :hackney, optional: false]}]},
"exjsx": {:hex, :exjsx, "3.2.0", "7136cc739ace295fc74c378f33699e5145bead4fdc1b4799822d0287489136fb", [:mix], [{:jsx, "~> 2.6.2", [hex: :jsx, optional: false]}]},
"fs": {:hex, :fs, "0.9.2", "ed17036c26c3f70ac49781ed9220a50c36775c6ca2cf8182d123b6566e49ec59", [:rebar], []},
+ "fuse": {:hex, :fuse, "2.4.0", "499ab65d3b1d291909973e1c25bdc55a17379fb26899f25eb68b6437a880de1b", [:rebar, :make], []},
"hackney": {:hex, :hackney, "1.6.1", "ddd22d42db2b50e6a155439c8811b8f6df61a4395de10509714ad2751c6da817", [:rebar3], [{:certifi, "0.4.0", [hex: :certifi, optional: false]}, {:idna, "1.2.0", [hex: :idna, optional: false]}, {:metrics, "1.0.1", [hex: :metrics, optional: false]}, {:mimerl, "1.0.2", [hex: :mimerl, optional: false]}, {:ssl_verify_fun, "1.1.0", [hex: :ssl_verify_fun, optional: false]}]},
"httparrot": {:hex, :httparrot, "0.4.1", "216b18b39ff206f71363cf17234a46f1846e6f3f364137d05d4e80fe70ec6e06", [:mix], [{:cowboy, "~> 1.0.0", [hex: :cowboy, optional: false]}, {:exjsx, "~> 3.0", [hex: :exjsx, optional: false]}]},
"ibrowse": {:hex, :ibrowse, "4.2.2", "b32b5bafcc77b7277eff030ed32e1acc3f610c64e9f6aea19822abcadf681b4b", [:rebar3], []},
"idna": {:hex, :idna, "1.2.0", "ac62ee99da068f43c50dc69acf700e03a62a348360126260e87f2b54eced86b2", [:rebar3], []},
"jsx": {:hex, :jsx, "2.6.2", "213721e058da0587a4bce3cc8a00ff6684ced229c8f9223245c6ff2c88fbaa5a", [:mix, :rebar], []},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], []},
"mimerl": {:hex, :mimerl, "1.0.2", "993f9b0e084083405ed8252b99460c4f0563e41729ab42d9074fd5e52439be88", [:rebar3], []},
"mix_test_watch": {:hex, :mix_test_watch, "0.2.6", "9fcc2b1b89d1594c4a8300959c19d50da2f0ff13642c8f681692a6e507f92cab", [:mix], [{:fs, "~> 0.9.1", [hex: :fs, optional: false]}]},
"poison": {:hex, :poison, "2.2.0", "4763b69a8a77bd77d26f477d196428b741261a761257ff1cf92753a0d4d24a63", [:mix], []},
"ranch": {:hex, :ranch, "1.2.1", "a6fb992c10f2187b46ffd17ce398ddf8a54f691b81768f9ef5f461ea7e28c762", [:make], []},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.0", "edee20847c42e379bf91261db474ffbe373f8acb56e9079acb6038d4e0bf414f", [:rebar, :make], []}}
diff --git a/test/tesla/middleware/fuse_test.exs b/test/tesla/middleware/fuse_test.exs
new file mode 100644
index 0000000..a6e147b
--- /dev/null
+++ b/test/tesla/middleware/fuse_test.exs
@@ -0,0 +1,49 @@
+defmodule FuseTest do
+ use ExUnit.Case, async: false
+
+ use Tesla.Middleware.TestCase, middleware: Tesla.Middleware.Fuse
+
+ defmodule Client do
+ use Tesla
+
+ plug Tesla.Middleware.Fuse
+ plug :report
+
+ def report(env, next) do
+ send self, :request_made
+ Tesla.run(env, next)
+ end
+
+ adapter fn env ->
+ case env.url do
+ "/ok" -> env
+ "/unavailable" -> {:error, :econnrefused}
+ end
+ end
+ end
+
+ setup do
+ Application.ensure_all_started(:fuse)
+ :fuse.reset(FuseTest.Client)
+
+ :ok
+ end
+
+ test "regular endpoint" do
+ assert %Tesla.Env{url: "/ok"} = Client.get("/ok")
+ end
+
+ test "unavailable endpoint" do
+ assert {:error, :unavailable} = Client.get("/unavailable")
+ assert_receive :request_made
+ assert {:error, :unavailable} = Client.get("/unavailable")
+ assert_receive :request_made
+ assert {:error, :unavailable} = Client.get("/unavailable")
+ assert_receive :request_made
+
+ assert {:error, :unavailable} = Client.get("/unavailable")
+ refute_receive :request_made
+ assert {:error, :unavailable} = Client.get("/unavailable")
+ refute_receive :request_made
+ end
+end

File Metadata

Mime Type
text/x-diff
Expires
Sun, Jan 19, 5:41 PM (1 d, 6 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
55351
Default Alt Text
(8 KB)

Event Timeline