Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

POC Telemetry #97

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
erlang 24.0.3
elixir 1.12.2-otp-24
erlang 25.1
elixir 1.14.1-otp-25
2 changes: 1 addition & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# This file is responsible for configuring your application
# and its dependencies with the aid of the Mix.Config module.
use Mix.Config
import Config

config :maxwell, default_adapter: Maxwell.Adapter.Hackney

Expand Down
2 changes: 1 addition & 1 deletion config/dev.exs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
use Mix.Config
import Config
2 changes: 1 addition & 1 deletion config/docs.exs
Original file line number Diff line number Diff line change
@@ -1 +1 @@
use Mix.Config
import Config
2 changes: 1 addition & 1 deletion config/test.exs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
use Mix.Config
import Config

config :ex_gram, token: "TOKEN", adapter: ExGram.Adapter.Test, updates: ExGram.Updates.Test
178 changes: 114 additions & 64 deletions lib/ex_gram/dispatcher.ex
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ defmodule ExGram.Dispatcher do

use GenServer

alias ExGram.Cnt
alias ExGram.{Cnt, Telemetry}

@type t :: %__MODULE__{
name: atom,
Expand Down Expand Up @@ -51,63 +51,92 @@ defmodule ExGram.Dispatcher do
{:ok, ops}
end

def handle_call(
{:update, u},
_from,
%{
handler: handler,
error_handler: error_handler
} = s
) do
cnt = create_cnt(s) |> Map.put(:update, u)

case apply_middlewares(cnt) do
%Cnt{halted: true} ->
# Logger.info "Middleware cancel"
true

cnt ->
info = extract_info(cnt)
spawn(fn -> call_handler(handler, info, cnt, error_handler) end)
end
def handle_call({:update, u}, _from, %{handler: handler, error_handler: error_handler} = state) do
cnt =
state
|> create_cnt()
|> Map.put(:update, u)

meta = %{context: cnt}

{:reply, :ok, s}
with_span(meta, fn ->
case apply_middlewares(cnt) do
%Cnt{halted: true} ->
{nil, %{result: :halted}}

cnt ->
info = extract_info(cnt)
spawn(fn -> call_handler(handler, info, cnt, error_handler) end)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the handlers executed with spawn are not being reported correctly 🤔
The easy solution would be to add another span on the call_handler

{nil, Map.merge(meta, %{info: info, result: :processed})}
end
end)

{:reply, :ok, state}
end

def handle_call({:update, _u}, _from, s) do
# Logger.error "Update, not update? #{inspect(u)}\nState: #{inspect(s)}"
{:reply, :error, s}
def handle_call({:update, u}, _from, state) do
cnt =
state
|> create_cnt()
|> Map.put(:update, u)

meta = %{context: cnt}

with_span(meta, fn -> {nil, Map.put(meta, :result, :error)} end)

{:reply, :error, state}
end

def handle_call(
{:message, origin, msg},
from,
%{handler: handler, error_handler: error_handler} = s
) do
def handle_call({:message, origin, msg}, from, state) do
%{handler: handler, error_handler: error_handler} = state

bot_message = {:bot_message, origin, msg}
cnt = create_cnt(s) |> Map.put(:message, bot_message) |> Map.put(:extra, %{from: from})

case apply_middlewares(cnt) do
%Cnt{halted: true} ->
{:reply, :halted, s}
cnt =
state
|> create_cnt()
|> Map.put(:message, bot_message)
|> Map.put(:extra, %{from: from})

cnt ->
response = call_handler(handler, {:bot_message, origin, msg}, cnt, error_handler)
{:reply, response, s}
end
meta = %{context: cnt}

result =
with_span(meta, fn ->
case apply_middlewares(cnt) do
%Cnt{halted: true} ->
{:halted, Map.put(meta, :result, :halted)}

cnt ->
response = call_handler(handler, {:bot_message, origin, msg}, cnt, error_handler)
{response, Map.put(meta, :result, :processed)}
end
end)

{:reply, result, state}
end

def handle_call(msg, from, %{handler: handler, error_handler: error_handler} = s) do
cnt = create_cnt(s) |> Map.put(:message, {:call, msg}) |> Map.put(:extra, %{from: from})
def handle_call(msg, from, %{handler: handler, error_handler: error_handler} = state) do
cnt =
state
|> create_cnt()
|> Map.put(:message, {:call, msg})
|> Map.put(:extra, %{from: from})

case apply_middlewares(cnt) do
%Cnt{halted: true} ->
{:reply, :halted, s}
meta = %{context: cnt}

cnt ->
response = call_handler(handler, {:call, msg}, cnt, error_handler)
{:reply, response, s}
end
result =
with_span(meta, fn ->
case apply_middlewares(cnt) do
%Cnt{halted: true} ->
{:halted, Map.put(meta, :result, :halted)}

cnt ->
response = call_handler(handler, {:call, msg}, cnt, error_handler)
{response, Map.put(meta, :result, :processed)}
end
end)

{:reply, result, state}
end

# EditedMessage
Expand All @@ -116,31 +145,50 @@ defmodule ExGram.Dispatcher do
# InlineQuery
# ChosenInlineResult

def handle_cast(msg, %{handler: handler, error_handler: error_handler} = s) do
cnt = create_cnt(s) |> Map.put(:message, {:cast, msg})
def handle_cast(msg, %{handler: handler, error_handler: error_handler} = state) do
cnt =
state
|> create_cnt()
|> Map.put(:message, {:cast, msg})

case apply_middlewares(cnt) do
%Cnt{halted: true} ->
{:noreply, s}
meta = %{context: cnt}

cnt ->
spawn(fn -> call_handler(handler, {:cast, msg}, cnt, error_handler) end)
{:noreply, s}
end
with_span(meta, fn ->
case apply_middlewares(cnt) do
%Cnt{halted: true} ->
{nil, Map.put(meta, :result, :halted)}

cnt ->
spawn(fn -> call_handler(handler, {:cast, msg}, cnt, error_handler) end)
{nil, Map.put(meta, :result, :processed)}
end
end)

{:noreply, state}
end

def handle_info(msg, %{handler: handler, error_handler: error_handler} = s) do
def handle_info(msg, %{handler: handler, error_handler: error_handler} = state) do
message = {:info, msg}
cnt = s |> create_cnt() |> Map.put(:message, message)

case apply_middlewares(cnt) do
%Cnt{halted: true} ->
{:noreply, s}
cnt =
state
|> create_cnt()
|> Map.put(:message, message)

cnt ->
call_handler(handler, message, cnt, error_handler)
{:noreply, s}
end
meta = %{context: cnt}

with_span(meta, fn ->
case apply_middlewares(cnt) do
%Cnt{halted: true} ->
{nil, Map.put(meta, :result, :halted)}

cnt ->
call_handler(handler, message, cnt, error_handler)
{nil, Map.put(meta, :result, :processed)}
end
end)

{:noreply, state}
end

defp create_cnt(%__MODULE__{
Expand Down Expand Up @@ -277,4 +325,6 @@ defmodule ExGram.Dispatcher do
defp call_handler({module, method}, args) do
apply(module, method, args)
end

defp with_span(meta, fun), do: Telemetry.span([:dispatcher], meta, fun)
end
7 changes: 7 additions & 0 deletions lib/ex_gram/telemetry.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
defmodule ExGram.Telemetry do
def span(event_name \\ [], meta \\ %{}, fun) do
event_name = [:ex_gram | event_name]

:telemetry.span(event_name, meta, fun)
end
end
7 changes: 4 additions & 3 deletions mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ defmodule ExGram.Mixfile do
package: package(),
description: description(),
source_url: "https://github.com/rockneurotiko/ex_gram",
elixir: "~> 1.6",
elixir: "~> 1.14",
elixirc_paths: elixirc_paths(Mix.env()),
build_embedded: Mix.env() == :prod,
start_permanent: Mix.env() == :prod,
Expand Down Expand Up @@ -54,7 +54,7 @@ defmodule ExGram.Mixfile do
defp deps do
[
# Tesla adapter
{:tesla, "~> 1.2", optional: true},
{:tesla, "~> 1.5", optional: true},
{:gun, "~> 1.3", optional: true},
# Maxwell or Tesla
{:hackney, "~> 1.12", optional: true},
Expand All @@ -67,7 +67,8 @@ defmodule ExGram.Mixfile do
{:dialyxir, "~> 1.0", only: [:dev], runtime: false},
{:credo, "~> 1.5", only: [:dev, :test], runtime: false},
{:ex_doc, "~> 0.23", only: :dev},
{:inch_ex, "~> 0.5.0", only: :docs}
{:inch_ex, "~> 0.5.0", only: :docs},
{:telemetry, "~> 1.1"}
]
end
end
17 changes: 9 additions & 8 deletions mix.lock
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
%{
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"certifi": {:hex, :certifi, "2.5.3", "70bdd7e7188c804f3a30ee0e7c99655bc35d8ac41c23e12325f36ab449b70651", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "ed516acb3929b101208a9d700062d520f3953da3b6b918d866106ffa980e1c10"},
"cowlib": {:hex, :cowlib, "2.6.0", "8aa629f81a0fc189f261dc98a42243fa842625feea3c7ec56c48f4ccdb55490f", [:rebar3], [], "hexpm", "45a1a08e05e4c66f2af665295955e337d52c2d33b1f1cf24d353cadeddf34992"},
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
"cowlib": {:hex, :cowlib, "2.7.3", "a7ffcd0917e6d50b4d5fb28e9e2085a0ceb3c97dea310505f7460ff5ed764ce9", [:rebar3], [], "hexpm", "1e1a3d176d52daebbecbbcdfd27c27726076567905c2a9d7398c54da9d225761"},
"credo": {:hex, :credo, "1.5.4", "9914180105b438e378e94a844ec3a5088ae5875626fc945b7c1462b41afc3198", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "cf51af45eadc0a3f39ba13b56fdac415c91b34f7b7533a13dc13550277141bc4"},
"dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"},
"earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"ex_doc": {:hex, :ex_doc, "0.23.0", "a069bc9b0bf8efe323ecde8c0d62afc13d308b1fa3d228b65bca5cf8703a529d", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}], "hexpm", "f5e2c4702468b2fd11b10d39416ddadd2fcdd173ba2a0285ebd92c39827a5a16"},
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
"gun": {:hex, :gun, "1.3.1", "1489fd96018431b89f401041a9ce0b02b45265247f0fdcf71273bf087c64ea4f", [:rebar3], [{:cowlib, "~> 2.6.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "f4d25a6946e34fe5d4d698db32b0f2a9bbb1e9fd75d23a0ffadbad373c48451f"},
"hackney": {:hex, :hackney, "1.17.0", "717ea195fd2f898d9fe9f1ce0afcc2621a41ecfe137fae57e7fe6e9484b9aa99", [:rebar3], [{:certifi, "~>2.5", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "64c22225f1ea8855f584720c0e5b3cd14095703af1c9fbc845ba042811dc671c"},
"gun": {:hex, :gun, "1.3.3", "cf8b51beb36c22b9c8df1921e3f2bc4d2b1f68b49ad4fbc64e91875aa14e16b4", [:rebar3], [{:cowlib, "~> 2.7.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "3106ce167f9c9723f849e4fb54ea4a4d814e3996ae243a1c828b256e749041e0"},
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~> 2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~> 6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~> 1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~> 1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~> 1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~> 0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
"inch_ex": {:hex, :inch_ex, "0.5.6", "418357418a553baa6d04eccd1b44171936817db61f4c0840112b420b8e378e67", [:mix], [{:poison, "~> 1.5 or ~> 2.0 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: false]}], "hexpm", "7123ca0450686a61416a06cd38e26af18fd0f8c1cff5214770a957c6e0724338"},
"jason": {:hex, :jason, "1.1.2", "b03dedea67a99223a2eaf9f1264ce37154564de899fd3d8b9a21b1a6fd64afe7", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fdf843bca858203ae1de16da2ee206f53416bbda5dc8c9e78f43243de4bc3afe"},
"jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"},
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
"makeup_elixir": {:hex, :makeup_elixir, "0.15.0", "98312c9f0d3730fde4049985a1105da5155bfe5c11e47bdc7406d88e01e4219b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "75ffa34ab1056b7e24844c90bfc62aaf6f3a37a15faa76b07bc5eba27e4a8b4a"},
"maxwell": {:hex, :maxwell, "2.3.1", "c9eec8d9938e094a69b9075e2ef93fbc6453017657f11b3a8435968850f26e2a", [:mix], [{:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:mimerl, "~> 1.2", [hex: :mimerl, repo: "hexpm", optional: false]}, {:poison, "~> 2.1 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "3968a02287412dae9b7b78dd1e42ef4f6537a2817959793d8dc989099847b8fe"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
"mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm", "6cbe761d6a0ca5a31a0931bf4c63204bceb64538e664a8ecf784a9a6f3b875f1"},
"mime": {:hex, :mime, "2.0.3", "3676436d3d1f7b81b5a2d2bd8405f412c677558c81b1c92be58c00562bb59095", [:mix], [], "hexpm", "27a30bf0db44d25eecba73755acf4068cbfe26a4372f9eb3e4ea3a45956bff6b"},
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"},
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"tesla": {:hex, :tesla, "1.3.0", "f35d72f029e608f9cdc6f6d6fcc7c66cf6d6512a70cfef9206b21b8bd0203a30", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 0.4", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "93a7cacc5ca47997759cfa1d3ab25501d291e490908006d5be56f37f89d96693"},
"telemetry": {:hex, :telemetry, "1.1.0", "a589817034a27eab11144ad24d5c0f9fab1f58173274b1e9bae7074af9cbee51", [:rebar3], [], "hexpm", "b727b2a1f75614774cff2d7565b64d0dfa5bd52ba517f16543e6fc7efcc0df48"},
"tesla": {:hex, :tesla, "1.5.0", "7ee3616be87024a2b7231ae14474310c9b999c3abb1f4f8dbc70f86bd9678eef", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.13", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:msgpax, "~> 2.3", [hex: :msgpax, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "1d0385e41fbd76af3961809088aef15dec4c2fdaab97b1c93c6484cb3695a122"},
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
}