mirror of
https://github.com/benbusby/farside.git
synced 2025-06-08 02:16:36 +00:00
refactor
This commit is contained in:
parent
03e46f81f8
commit
84caea3af2
17 changed files with 402 additions and 140 deletions
209
.credo.exs
Normal file
209
.credo.exs
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
# This file contains the configuration for Credo and you are probably reading
|
||||||
|
# this after creating it with `mix credo.gen.config`.
|
||||||
|
#
|
||||||
|
# If you find anything wrong or unclear in this file, please report an
|
||||||
|
# issue on GitHub: https://github.com/rrrene/credo/issues
|
||||||
|
#
|
||||||
|
%{
|
||||||
|
#
|
||||||
|
# You can have as many configs as you like in the `configs:` field.
|
||||||
|
configs: [
|
||||||
|
%{
|
||||||
|
#
|
||||||
|
# Run any config using `mix credo -C <name>`. If no config name is given
|
||||||
|
# "default" is used.
|
||||||
|
#
|
||||||
|
name: "default",
|
||||||
|
#
|
||||||
|
# These are the files included in the analysis:
|
||||||
|
files: %{
|
||||||
|
#
|
||||||
|
# You can give explicit globs or simply directories.
|
||||||
|
# In the latter case `**/*.{ex,exs}` will be used.
|
||||||
|
#
|
||||||
|
included: [
|
||||||
|
"lib/",
|
||||||
|
"src/",
|
||||||
|
"test/",
|
||||||
|
"web/",
|
||||||
|
"apps/*/lib/",
|
||||||
|
"apps/*/src/",
|
||||||
|
"apps/*/test/",
|
||||||
|
"apps/*/web/"
|
||||||
|
],
|
||||||
|
excluded: [
|
||||||
|
~r"/_build/",
|
||||||
|
~r"/deps/",
|
||||||
|
~r"/node_modules/",
|
||||||
|
~r"/package-lock.json",
|
||||||
|
~r"/package.json"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
#
|
||||||
|
# Load and configure plugins here:
|
||||||
|
#
|
||||||
|
plugins: [],
|
||||||
|
#
|
||||||
|
# If you create your own checks, you must specify the source files for
|
||||||
|
# them here, so they can be loaded by Credo before running the analysis.
|
||||||
|
#
|
||||||
|
requires: [],
|
||||||
|
#
|
||||||
|
# If you want to enforce a style guide and need a more traditional linting
|
||||||
|
# experience, you can change `strict` to `true` below:
|
||||||
|
#
|
||||||
|
strict: false,
|
||||||
|
#
|
||||||
|
# To modify the timeout for parsing files, change this value:
|
||||||
|
#
|
||||||
|
parse_timeout: 120_000,
|
||||||
|
#
|
||||||
|
# If you want to use uncolored output by default, you can change `color`
|
||||||
|
# to `false` below:
|
||||||
|
#
|
||||||
|
color: true,
|
||||||
|
#
|
||||||
|
# You can customize the parameters of any check by adding a second element
|
||||||
|
# to the tuple.
|
||||||
|
#
|
||||||
|
# To disable a check put `false` as second element:
|
||||||
|
#
|
||||||
|
# {Credo.Check.Design.DuplicatedCode, false}
|
||||||
|
#
|
||||||
|
checks: %{
|
||||||
|
enabled: [
|
||||||
|
#
|
||||||
|
## Consistency Checks
|
||||||
|
#
|
||||||
|
{Credo.Check.Consistency.ExceptionNames, []},
|
||||||
|
{Credo.Check.Consistency.LineEndings, []},
|
||||||
|
{Credo.Check.Consistency.ParameterPatternMatching, []},
|
||||||
|
{Credo.Check.Consistency.SpaceAroundOperators, []},
|
||||||
|
{Credo.Check.Consistency.SpaceInParentheses, []},
|
||||||
|
{Credo.Check.Consistency.TabsOrSpaces, []},
|
||||||
|
|
||||||
|
#
|
||||||
|
## Design Checks
|
||||||
|
#
|
||||||
|
# You can customize the priority of any check
|
||||||
|
# Priority values are: `low, normal, high, higher`
|
||||||
|
#
|
||||||
|
{Credo.Check.Design.AliasUsage,
|
||||||
|
[priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]},
|
||||||
|
# You can also customize the exit_status of each check.
|
||||||
|
# set this value to 0 (zero).
|
||||||
|
#
|
||||||
|
{Credo.Check.Design.TagFIXME, []},
|
||||||
|
|
||||||
|
#
|
||||||
|
## Readability Checks
|
||||||
|
#
|
||||||
|
{Credo.Check.Readability.AliasOrder, []},
|
||||||
|
{Credo.Check.Readability.FunctionNames, []},
|
||||||
|
{Credo.Check.Readability.LargeNumbers, []},
|
||||||
|
{Credo.Check.Readability.ModuleAttributeNames, []},
|
||||||
|
{Credo.Check.Readability.ModuleDoc, []},
|
||||||
|
{Credo.Check.Readability.ModuleNames, []},
|
||||||
|
{Credo.Check.Readability.ParenthesesInCondition, []},
|
||||||
|
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, []},
|
||||||
|
{Credo.Check.Readability.PipeIntoAnonymousFunctions, []},
|
||||||
|
{Credo.Check.Readability.PredicateFunctionNames, []},
|
||||||
|
{Credo.Check.Readability.PreferImplicitTry, []},
|
||||||
|
{Credo.Check.Readability.RedundantBlankLines, []},
|
||||||
|
{Credo.Check.Readability.Semicolons, []},
|
||||||
|
{Credo.Check.Readability.SpaceAfterCommas, []},
|
||||||
|
{Credo.Check.Readability.StrictModuleLayout, []},
|
||||||
|
{Credo.Check.Readability.StringSigils, []},
|
||||||
|
{Credo.Check.Readability.TrailingBlankLine, []},
|
||||||
|
{Credo.Check.Readability.TrailingWhiteSpace, []},
|
||||||
|
{Credo.Check.Readability.UnnecessaryAliasExpansion, []},
|
||||||
|
{Credo.Check.Readability.VariableNames, []},
|
||||||
|
{Credo.Check.Readability.WithSingleClause, []},
|
||||||
|
|
||||||
|
#
|
||||||
|
## Refactoring Opportunities
|
||||||
|
#
|
||||||
|
{Credo.Check.Refactor.Apply, []},
|
||||||
|
# {Credo.Check.Refactor.CondStatements, []},
|
||||||
|
# {Credo.Check.Refactor.CyclomaticComplexity, []},
|
||||||
|
{Credo.Check.Refactor.FunctionArity, []},
|
||||||
|
# should be activated after elixir version upgrade
|
||||||
|
{Credo.Check.Refactor.MapInto, false},
|
||||||
|
{Credo.Check.Refactor.MatchInCondition, []},
|
||||||
|
{Credo.Check.Refactor.NegatedConditionsInUnless, []},
|
||||||
|
{Credo.Check.Refactor.NegatedConditionsWithElse, []},
|
||||||
|
# {Credo.Check.Refactor.Nesting, []},
|
||||||
|
{Credo.Check.Refactor.UnlessWithElse, []},
|
||||||
|
{Credo.Check.Refactor.WithClauses, []},
|
||||||
|
{Credo.Check.Refactor.RedundantWithClauseResult, []},
|
||||||
|
{Credo.Check.Refactor.FilterFilter, []},
|
||||||
|
#
|
||||||
|
## Warnings
|
||||||
|
#
|
||||||
|
{Credo.Check.Warning.BoolOperationOnSameValues, []},
|
||||||
|
{Credo.Check.Warning.ExpensiveEmptyEnumCheck, []},
|
||||||
|
{Credo.Check.Warning.IExPry, []},
|
||||||
|
{Credo.Check.Warning.IoInspect, []},
|
||||||
|
# should be activated after elixir version upgrade
|
||||||
|
{Credo.Check.Warning.LazyLogging, false},
|
||||||
|
{Credo.Check.Warning.OperationOnSameValues, []},
|
||||||
|
{Credo.Check.Warning.OperationWithConstantResult, []},
|
||||||
|
{Credo.Check.Warning.RaiseInsideRescue, []},
|
||||||
|
{Credo.Check.Warning.SpecWithStruct, []},
|
||||||
|
{Credo.Check.Warning.WrongTestFileExtension, []},
|
||||||
|
{Credo.Check.Warning.UnusedEnumOperation, []},
|
||||||
|
{Credo.Check.Warning.UnusedFileOperation, []},
|
||||||
|
{Credo.Check.Warning.UnusedKeywordOperation, []},
|
||||||
|
{Credo.Check.Warning.UnusedListOperation, []},
|
||||||
|
{Credo.Check.Warning.UnusedPathOperation, []},
|
||||||
|
{Credo.Check.Warning.UnusedRegexOperation, []},
|
||||||
|
{Credo.Check.Warning.UnusedStringOperation, []},
|
||||||
|
{Credo.Check.Warning.UnusedTupleOperation, []},
|
||||||
|
{Credo.Check.Warning.UnsafeExec, []}
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Checks scheduled for next check update (opt-in for now, just replace `false` with `[]`)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Controversial and experimental checks (opt-in, just replace `false` with `[]`)
|
||||||
|
#
|
||||||
|
],
|
||||||
|
disabled: [
|
||||||
|
{Credo.Check.Design.TagTODO, false},
|
||||||
|
{Credo.Check.Consistency.MultiAliasImportRequireUse, false},
|
||||||
|
{Credo.Check.Consistency.UnusedVariableNames, false},
|
||||||
|
{Credo.Check.Design.DuplicatedCode, false},
|
||||||
|
{Credo.Check.Readability.AliasAs, false},
|
||||||
|
{Credo.Check.Readability.BlockPipe, false},
|
||||||
|
{Credo.Check.Readability.ImplTrue, false},
|
||||||
|
{Credo.Check.Readability.MaxLineLength, false},
|
||||||
|
{Credo.Check.Readability.MultiAlias, false},
|
||||||
|
{Credo.Check.Readability.SeparateAliasRequire, false},
|
||||||
|
{Credo.Check.Readability.SinglePipe, false},
|
||||||
|
{Credo.Check.Readability.Specs, false},
|
||||||
|
{Credo.Check.Readability.StrictModuleLayout, false},
|
||||||
|
{Credo.Check.Readability.WithCustomTaggedTuple, false},
|
||||||
|
{Credo.Check.Refactor.ABCSize, false},
|
||||||
|
{Credo.Check.Refactor.AppendSingleItem, false},
|
||||||
|
{Credo.Check.Refactor.DoubleBooleanNegation, false},
|
||||||
|
{Credo.Check.Refactor.LongQuoteBlocks, false},
|
||||||
|
{Credo.Check.Refactor.MapJoin, false},
|
||||||
|
{Credo.Check.Refactor.ModuleDependencies, false},
|
||||||
|
{Credo.Check.Refactor.NegatedIsNil, false},
|
||||||
|
{Credo.Check.Refactor.PipeChainStart, false},
|
||||||
|
{Credo.Check.Refactor.RejectReject, false},
|
||||||
|
{Credo.Check.Refactor.VariableRebinding, false},
|
||||||
|
{Credo.Check.Warning.LeakyEnvironment, false},
|
||||||
|
{Credo.Check.Warning.MapGetUnsafePass, false},
|
||||||
|
{Credo.Check.Warning.MixEnv, false},
|
||||||
|
{Credo.Check.Warning.UnsafeToAtom, false},
|
||||||
|
{Credo.Check.Warning.ApplicationConfigInModuleAttribute, false}
|
||||||
|
]
|
||||||
|
#
|
||||||
|
# Custom checks can be created using `mix credo.gen.check`.
|
||||||
|
#
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,8 +1,6 @@
|
||||||
import Config
|
import Config
|
||||||
|
|
||||||
config :farside,
|
config :farside,
|
||||||
update_file: ".update-results",
|
|
||||||
service_prefix: "service-",
|
|
||||||
index: "index.eex",
|
index: "index.eex",
|
||||||
route: "route.eex",
|
route: "route.eex",
|
||||||
headers: [
|
headers: [
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
defmodule Farside do
|
defmodule Farside do
|
||||||
@service_prefix Application.fetch_env!(:farside, :service_prefix)
|
@moduledoc """
|
||||||
|
Farside
|
||||||
|
main application functions
|
||||||
|
|
||||||
|
This is where we define relation between available services and their parent service.
|
||||||
|
This enables Farside to redirect with links such as:
|
||||||
|
farside.link/https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
||||||
|
"""
|
||||||
|
|
||||||
# Define relation between available services and their parent service.
|
|
||||||
# This enables Farside to redirect with links such as:
|
|
||||||
# farside.link/https://www.youtube.com/watch?v=dQw4w9WgXcQ
|
|
||||||
@youtube_regex ~r/youtu(.be|be.com)|invidious|piped/
|
@youtube_regex ~r/youtu(.be|be.com)|invidious|piped/
|
||||||
@reddit_regex ~r/reddit.com|libreddit|teddit/
|
@reddit_regex ~r/reddit.com|libreddit|teddit/
|
||||||
@instagram_regex ~r/instagram.com|bibliogram/
|
@instagram_regex ~r/instagram.com|bibliogram/
|
||||||
|
@ -35,12 +39,10 @@ defmodule Farside do
|
||||||
alias Farside.LastUpdated
|
alias Farside.LastUpdated
|
||||||
|
|
||||||
def get_services_map do
|
def get_services_map do
|
||||||
services_map =
|
|
||||||
Farside.Instance.Supervisor.list()
|
Farside.Instance.Supervisor.list()
|
||||||
|> Enum.map(fn service ->
|
|> Enum.map(fn service ->
|
||||||
data = :ets.lookup(String.to_atom(service), :default) |> List.first()
|
data = :ets.lookup(String.to_atom(service), :default) |> List.first()
|
||||||
|
|
||||||
instances =
|
|
||||||
case is_nil(data) do
|
case is_nil(data) do
|
||||||
true ->
|
true ->
|
||||||
[]
|
[]
|
||||||
|
@ -149,18 +151,4 @@ defmodule Farside do
|
||||||
instance
|
instance
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def save_results(file, data) do
|
|
||||||
if System.get_env("MIX_ENV") == "dev" do
|
|
||||||
{:ok, file} = File.open(file, [:append])
|
|
||||||
bin = :erlang.term_to_binary(data)
|
|
||||||
IO.binwrite(file, bin)
|
|
||||||
File.close(file)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def restore_term(file) do
|
|
||||||
{:ok, bin} = File.read(file)
|
|
||||||
:erlang.binary_to_term(bin)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -78,7 +78,18 @@ defmodule Farside.Application do
|
||||||
|
|
||||||
struct(%Service{}, service_atom)
|
struct(%Service{}, service_atom)
|
||||||
|> Farside.Instance.Supervisor.start()
|
|> Farside.Instance.Supervisor.start()
|
||||||
|> HealthyCheck.load()
|
end
|
||||||
|
|
||||||
|
response
|
||||||
|
|> maybe_run()
|
||||||
|
end
|
||||||
|
|
||||||
|
def maybe_run(response) do
|
||||||
|
if is_nil(System.get_env("FARSIDE_TEST")) do
|
||||||
|
Task.start(fn ->
|
||||||
|
Process.sleep(10_000)
|
||||||
|
UnHealthyCheck.run()
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
response
|
response
|
||||||
|
|
|
@ -5,6 +5,8 @@ defmodule Farside.Server.DeadCheck do
|
||||||
use Task
|
use Task
|
||||||
alias Farside.LastUpdated
|
alias Farside.LastUpdated
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
|
||||||
def child_spec(args) do
|
def child_spec(args) do
|
||||||
%{
|
%{
|
||||||
id: __MODULE__,
|
id: __MODULE__,
|
||||||
|
@ -20,7 +22,7 @@ defmodule Farside.Server.DeadCheck do
|
||||||
def poll() do
|
def poll() do
|
||||||
receive do
|
receive do
|
||||||
after
|
after
|
||||||
1_200_000 ->
|
86_400_000 ->
|
||||||
run()
|
run()
|
||||||
poll()
|
poll()
|
||||||
end
|
end
|
||||||
|
@ -29,6 +31,8 @@ defmodule Farside.Server.DeadCheck do
|
||||||
def run() do
|
def run() do
|
||||||
LastUpdated.value(DateTime.utc_now())
|
LastUpdated.value(DateTime.utc_now())
|
||||||
|
|
||||||
|
Logger.info("Dead Service Check Running")
|
||||||
|
|
||||||
Registry.dispatch(:status, "dead", fn entries ->
|
Registry.dispatch(:status, "dead", fn entries ->
|
||||||
for {pid, _} <- entries, do: GenServer.cast(pid, :check)
|
for {pid, _} <- entries, do: GenServer.cast(pid, :check)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -5,6 +5,8 @@ defmodule Farside.Server.HealthyCheck do
|
||||||
use Task
|
use Task
|
||||||
alias Farside.LastUpdated
|
alias Farside.LastUpdated
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
|
||||||
def child_spec(args) do
|
def child_spec(args) do
|
||||||
%{
|
%{
|
||||||
id: __MODULE__,
|
id: __MODULE__,
|
||||||
|
@ -20,27 +22,19 @@ defmodule Farside.Server.HealthyCheck do
|
||||||
def poll() do
|
def poll() do
|
||||||
receive do
|
receive do
|
||||||
after
|
after
|
||||||
90_000 ->
|
300_000 ->
|
||||||
run()
|
run()
|
||||||
poll()
|
poll()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def load(params) do
|
|
||||||
Registry.dispatch(:status, "healthy", fn entries ->
|
|
||||||
for {pid, url} <- entries do
|
|
||||||
GenServer.cast(pid, :check)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
params
|
|
||||||
end
|
|
||||||
|
|
||||||
def run() do
|
def run() do
|
||||||
LastUpdated.value(DateTime.utc_now())
|
LastUpdated.value(DateTime.utc_now())
|
||||||
|
|
||||||
|
Logger.info("Healthy Service Check Running")
|
||||||
|
|
||||||
Registry.dispatch(:status, "healthy", fn entries ->
|
Registry.dispatch(:status, "healthy", fn entries ->
|
||||||
for {pid, url} <- entries do
|
for {pid, _url} <- entries do
|
||||||
GenServer.cast(pid, :check)
|
GenServer.cast(pid, :check)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
defmodule Farside.Http do
|
defmodule Farside.Http do
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
@moduledoc """
|
||||||
|
Http
|
||||||
|
the http client
|
||||||
|
"""
|
||||||
|
|
||||||
@headers Application.fetch_env!(:farside, :headers)
|
@headers Application.fetch_env!(:farside, :headers)
|
||||||
@queries Application.fetch_env!(:farside, :queries)
|
@queries Application.fetch_env!(:farside, :queries)
|
||||||
@recv_timeout String.to_integer(Application.fetch_env!(:farside, :recv_timeout))
|
@recv_timeout String.to_integer(Application.fetch_env!(:farside, :recv_timeout))
|
||||||
|
@ -108,11 +113,11 @@ defmodule Farside.Http do
|
||||||
nil
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
unless is_nil(data) do
|
if is_nil(data) do
|
||||||
|
:bad
|
||||||
|
else
|
||||||
{_test_url, value, _service} = data
|
{_test_url, value, _service} = data
|
||||||
value
|
value
|
||||||
else
|
|
||||||
:bad
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
defmodule Farside.Instance do
|
defmodule Farside.Instance do
|
||||||
use GenServer
|
use GenServer
|
||||||
|
|
||||||
require Logger
|
@moduledoc """
|
||||||
|
Instance
|
||||||
|
this will store the pointer to ets
|
||||||
|
"""
|
||||||
|
|
||||||
alias Farside.Http
|
require Logger
|
||||||
|
|
||||||
@registry_name :instance
|
@registry_name :instance
|
||||||
|
|
||||||
|
@ -15,6 +18,7 @@ defmodule Farside.Instance do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
def init(init_arg) do
|
def init(init_arg) do
|
||||||
ref =
|
ref =
|
||||||
:ets.new(String.to_atom(init_arg.type), [
|
:ets.new(String.to_atom(init_arg.type), [
|
||||||
|
@ -40,6 +44,7 @@ defmodule Farside.Instance do
|
||||||
GenServer.call(__MODULE__, :shutdown)
|
GenServer.call(__MODULE__, :shutdown)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
def handle_call(
|
def handle_call(
|
||||||
:shutdown,
|
:shutdown,
|
||||||
_from,
|
_from,
|
||||||
|
@ -48,6 +53,7 @@ defmodule Farside.Instance do
|
||||||
{:stop, {:ok, "Normal Shutdown"}, state}
|
{:stop, {:ok, "Normal Shutdown"}, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
def handle_cast(
|
def handle_cast(
|
||||||
:shutdown,
|
:shutdown,
|
||||||
state
|
state
|
||||||
|
@ -61,7 +67,7 @@ defmodule Farside.Instance do
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:DOWN, ref, :process, _pid, _reason}, {names, refs}) do
|
def handle_info({:DOWN, _ref, :process, _pid, _reason}, {names, refs}) do
|
||||||
:ets.delete(names)
|
:ets.delete(names)
|
||||||
{:noreply, {names, refs}}
|
{:noreply, {names, refs}}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
defmodule Farside.Instance.Supervisor do
|
defmodule Farside.Instance.Supervisor do
|
||||||
use DynamicSupervisor
|
use DynamicSupervisor
|
||||||
|
|
||||||
alias __MODULE__, as: SUPERVISOR
|
@moduledoc """
|
||||||
|
Instance Supervisor
|
||||||
|
this will supervise the instance
|
||||||
|
"""
|
||||||
|
|
||||||
alias Farside.Instance, as: SERVER
|
alias Farside.Instance, as: SERVER
|
||||||
|
|
||||||
@name :instance_supervisor
|
@name :instance_supervisor
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
defmodule Farside.LastUpdated do
|
defmodule Farside.LastUpdated do
|
||||||
use Agent
|
use Agent
|
||||||
|
|
||||||
|
@moduledoc nil
|
||||||
|
|
||||||
def start_link(initial_value) do
|
def start_link(initial_value) do
|
||||||
Agent.start_link(fn -> initial_value end, name: __MODULE__)
|
Agent.start_link(fn -> initial_value end, name: __MODULE__)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
defmodule Farside.Service do
|
defmodule Farside.Service do
|
||||||
use GenServer
|
use GenServer
|
||||||
|
|
||||||
|
@moduledoc """
|
||||||
|
Service
|
||||||
|
this will store the service state
|
||||||
|
"""
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
alias Farside.Http
|
alias Farside.Http
|
||||||
|
@ -21,19 +26,22 @@ defmodule Farside.Service do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
def init(data) do
|
def init(data) do
|
||||||
initial_state = %__MODULE__{
|
initial_state = %__MODULE__{
|
||||||
url: data.url,
|
url: data.url,
|
||||||
type: data.type,
|
type: data.type,
|
||||||
test_url: data.test_url,
|
test_url: data.test_url,
|
||||||
last_update: nil,
|
last_update:
|
||||||
|
DateTime.utc_now()
|
||||||
|
|> DateTime.add(-86_400, :second),
|
||||||
status: []
|
status: []
|
||||||
}
|
}
|
||||||
|
|
||||||
healthy = "#{data.type}_healthy"
|
unhealthy = "#{data.type}_unhealthy"
|
||||||
|
|
||||||
Registry.register(:status, healthy, data.url)
|
Registry.register(:status, unhealthy, data.url)
|
||||||
Registry.register(:status, "healthy", data.url)
|
Registry.register(:status, "unhealthy", data.url)
|
||||||
{:ok, initial_state}
|
{:ok, initial_state}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -46,6 +54,7 @@ defmodule Farside.Service do
|
||||||
GenServer.call(__MODULE__, :shutdown)
|
GenServer.call(__MODULE__, :shutdown)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
def handle_call(
|
def handle_call(
|
||||||
:shutdown,
|
:shutdown,
|
||||||
_from,
|
_from,
|
||||||
|
@ -54,28 +63,6 @@ defmodule Farside.Service do
|
||||||
{:stop, {:ok, "Normal Shutdown"}, state}
|
{:stop, {:ok, "Normal Shutdown"}, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_cast(
|
|
||||||
:shutdown,
|
|
||||||
state
|
|
||||||
) do
|
|
||||||
{:stop, :normal, state}
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc false
|
|
||||||
def via_tuple(id, registry \\ @registry_name) do
|
|
||||||
{:via, Registry, {registry, id}}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl true
|
|
||||||
def handle_info({:DOWN, ref, :process, _pid, _reason}, data) do
|
|
||||||
{:noreply, data}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl true
|
|
||||||
def handle_info(_msg, state) do
|
|
||||||
{:noreply, state}
|
|
||||||
end
|
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_cast(:load, state) do
|
def handle_cast(:load, state) do
|
||||||
reply = Http.test_service(state)
|
reply = Http.test_service(state)
|
||||||
|
@ -91,6 +78,13 @@ defmodule Farside.Service do
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_cast(:check, state) do
|
def handle_cast(:check, state) do
|
||||||
|
dt =
|
||||||
|
DateTime.utc_now()
|
||||||
|
|> DateTime.add(-60, :second)
|
||||||
|
|
||||||
|
state =
|
||||||
|
case DateTime.compare(dt, state.last_update) do
|
||||||
|
:gt ->
|
||||||
reply = Http.test_service(state)
|
reply = Http.test_service(state)
|
||||||
|
|
||||||
status = state.status ++ [reply]
|
status = state.status ++ [reply]
|
||||||
|
@ -119,7 +113,6 @@ defmodule Farside.Service do
|
||||||
Registry.unregister_match(:status, unhealthy, state.url)
|
Registry.unregister_match(:status, unhealthy, state.url)
|
||||||
Registry.unregister_match(:status, dead, state.url)
|
Registry.unregister_match(:status, dead, state.url)
|
||||||
|
|
||||||
state =
|
|
||||||
if reply != :good do
|
if reply != :good do
|
||||||
filtered = Enum.reject(status, fn x -> x == :good end)
|
filtered = Enum.reject(status, fn x -> x == :good end)
|
||||||
|
|
||||||
|
@ -142,6 +135,33 @@ defmodule Farside.Service do
|
||||||
state
|
state
|
||||||
end
|
end
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
%{state | last_update: DateTime.utc_now()}
|
||||||
|
end
|
||||||
|
|
||||||
|
{:noreply, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_cast(
|
||||||
|
:shutdown,
|
||||||
|
state
|
||||||
|
) do
|
||||||
|
{:stop, :normal, state}
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc false
|
||||||
|
def via_tuple(id, registry \\ @registry_name) do
|
||||||
|
{:via, Registry, {registry, id}}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info({:DOWN, _ref, :process, _pid, _reason}, data) do
|
||||||
|
{:noreply, data}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info(_msg, state) do
|
||||||
{:noreply, state}
|
{:noreply, state}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
defmodule Farside.Service.Supervisor do
|
defmodule Farside.Service.Supervisor do
|
||||||
use DynamicSupervisor
|
use DynamicSupervisor
|
||||||
|
|
||||||
|
@moduledoc """
|
||||||
|
Service Supervisor
|
||||||
|
this will supervise the service
|
||||||
|
"""
|
||||||
|
|
||||||
alias __MODULE__, as: SUPERVISOR
|
alias __MODULE__, as: SUPERVISOR
|
||||||
alias Farside.Service, as: SERVER
|
alias Farside.Service, as: SERVER
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@ defmodule Farside.Throttle do
|
||||||
import Plug.Conn
|
import Plug.Conn
|
||||||
use PlugAttack
|
use PlugAttack
|
||||||
|
|
||||||
|
@moduledoc nil
|
||||||
|
|
||||||
rule "throttle per ip", conn do
|
rule "throttle per ip", conn do
|
||||||
# throttle to 1 request per second
|
# throttle to 1 request per second
|
||||||
throttle(conn.remote_ip,
|
throttle(conn.remote_ip,
|
||||||
|
|
|
@ -5,6 +5,8 @@ defmodule Farside.Server.UnHealthyCheck do
|
||||||
use Task
|
use Task
|
||||||
alias Farside.LastUpdated
|
alias Farside.LastUpdated
|
||||||
|
|
||||||
|
require Logger
|
||||||
|
|
||||||
def child_spec(args) do
|
def child_spec(args) do
|
||||||
%{
|
%{
|
||||||
id: __MODULE__,
|
id: __MODULE__,
|
||||||
|
@ -20,7 +22,7 @@ defmodule Farside.Server.UnHealthyCheck do
|
||||||
def poll() do
|
def poll() do
|
||||||
receive do
|
receive do
|
||||||
after
|
after
|
||||||
120_000 ->
|
200_000 ->
|
||||||
run()
|
run()
|
||||||
poll()
|
poll()
|
||||||
end
|
end
|
||||||
|
@ -29,6 +31,8 @@ defmodule Farside.Server.UnHealthyCheck do
|
||||||
def run() do
|
def run() do
|
||||||
LastUpdated.value(DateTime.utc_now())
|
LastUpdated.value(DateTime.utc_now())
|
||||||
|
|
||||||
|
Logger.info("Unhealthy Service Check Running")
|
||||||
|
|
||||||
Registry.dispatch(:status, "unhealthy", fn entries ->
|
Registry.dispatch(:status, "unhealthy", fn entries ->
|
||||||
for {pid, _} <- entries, do: GenServer.cast(pid, :check)
|
for {pid, _} <- entries, do: GenServer.cast(pid, :check)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
defmodule Service do
|
defmodule Service do
|
||||||
|
@moduledoc nil
|
||||||
|
|
||||||
defstruct type: nil,
|
defstruct type: nil,
|
||||||
test_url: nil,
|
test_url: nil,
|
||||||
fallback: nil,
|
fallback: nil,
|
||||||
|
|
2
mix.exs
2
mix.exs
|
@ -41,6 +41,8 @@ defmodule Farside.MixProject do
|
||||||
{:jason, "~> 1.1"},
|
{:jason, "~> 1.1"},
|
||||||
{:plug_attack, "~> 0.4.2"},
|
{:plug_attack, "~> 0.4.2"},
|
||||||
{:plug_cowboy, "~> 2.0"},
|
{:plug_cowboy, "~> 2.0"},
|
||||||
|
{:credo, "~> 1.6.3", only: [:dev, :test], runtime: false},
|
||||||
|
{:mix_audit, "~> 1.0.0", only: [:dev, :test], runtime: false},
|
||||||
{:bakeware, runtime: false, only: :cli}
|
{:bakeware, runtime: false, only: :cli}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
6
mix.lock
6
mix.lock
|
@ -1,13 +1,16 @@
|
||||||
%{
|
%{
|
||||||
"artificery": {:hex, :artificery, "0.4.3", "0bc4260f988dcb9dda4b23f9fc3c6c8b99a6220a331534fdf5bf2fd0d4333b02", [:mix], [], "hexpm", "12e95333a30e20884e937abdbefa3e7f5e05609c2ba8cf37b33f000b9ffc0504"},
|
"artificery": {:hex, :artificery, "0.4.3", "0bc4260f988dcb9dda4b23f9fc3c6c8b99a6220a331534fdf5bf2fd0d4333b02", [:mix], [], "hexpm", "12e95333a30e20884e937abdbefa3e7f5e05609c2ba8cf37b33f000b9ffc0504"},
|
||||||
"bakeware": {:hex, :bakeware, "0.2.4", "0aaf49b34f4bab2aa433f9ff1485d9401e421603160abd6d269c469fc7b65212", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "7b97bcf6fbeee53bb32441d6c495bf478d26f9575633cfef6831e421e86ada6d"},
|
"bakeware": {:hex, :bakeware, "0.2.4", "0aaf49b34f4bab2aa433f9ff1485d9401e421603160abd6d269c469fc7b65212", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "7b97bcf6fbeee53bb32441d6c495bf478d26f9575633cfef6831e421e86ada6d"},
|
||||||
|
"bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
|
||||||
"certifi": {:hex, :certifi, "2.8.0", "d4fb0a6bb20b7c9c3643e22507e42f356ac090a1dcea9ab99e27e0376d695eba", [:rebar3], [], "hexpm", "6ac7efc1c6f8600b08d625292d4bbf584e14847ce1b6b5c44d983d273e1097ea"},
|
"certifi": {:hex, :certifi, "2.8.0", "d4fb0a6bb20b7c9c3643e22507e42f356ac090a1dcea9ab99e27e0376d695eba", [:rebar3], [], "hexpm", "6ac7efc1c6f8600b08d625292d4bbf584e14847ce1b6b5c44d983d273e1097ea"},
|
||||||
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
|
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
|
||||||
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
|
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"},
|
||||||
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
|
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
|
||||||
|
"credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [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", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"},
|
||||||
"crontab": {:hex, :crontab, "1.1.10", "dc9bb1f4299138d47bce38341f5dcbee0aa6c205e864fba7bc847f3b5cb48241", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "1347d889d1a0eda997990876b4894359e34bfbbd688acbb0ba28a2795ca40685"},
|
"crontab": {:hex, :crontab, "1.1.10", "dc9bb1f4299138d47bce38341f5dcbee0aa6c205e864fba7bc847f3b5cb48241", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "1347d889d1a0eda997990876b4894359e34bfbbd688acbb0ba28a2795ca40685"},
|
||||||
"distillery": {:hex, :distillery, "2.1.1", "f9332afc2eec8a1a2b86f22429e068ef35f84a93ea1718265e740d90dd367814", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm", "bbc7008b0161a6f130d8d903b5b3232351fccc9c31a991f8fcbf2a12ace22995"},
|
"distillery": {:hex, :distillery, "2.1.1", "f9332afc2eec8a1a2b86f22429e068ef35f84a93ea1718265e740d90dd367814", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm", "bbc7008b0161a6f130d8d903b5b3232351fccc9c31a991f8fcbf2a12ace22995"},
|
||||||
"elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"},
|
"elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"},
|
||||||
|
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
|
||||||
"gen_stage": {:hex, :gen_stage, "1.1.2", "b1656cd4ba431ed02c5656fe10cb5423820847113a07218da68eae5d6a260c23", [:mix], [], "hexpm", "9e39af23140f704e2b07a3e29d8f05fd21c2aaf4088ff43cb82be4b9e3148d02"},
|
"gen_stage": {:hex, :gen_stage, "1.1.2", "b1656cd4ba431ed02c5656fe10cb5423820847113a07218da68eae5d6a260c23", [:mix], [], "hexpm", "9e39af23140f704e2b07a3e29d8f05fd21c2aaf4088ff43cb82be4b9e3148d02"},
|
||||||
"hackney": {:hex, :hackney, "1.18.0", "c4443d960bb9fba6d01161d01cd81173089686717d9490e5d3606644c48d121f", [:rebar3], [{:certifi, "~>2.8.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", "9afcda620704d720db8c6a3123e9848d09c87586dc1c10479c42627b905b5c5e"},
|
"hackney": {:hex, :hackney, "1.18.0", "c4443d960bb9fba6d01161d01cd81173089686717d9490e5d3606644c48d121f", [:rebar3], [{:certifi, "~>2.8.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", "9afcda620704d720db8c6a3123e9848d09c87586dc1c10479c42627b905b5c5e"},
|
||||||
"httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"},
|
"httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"},
|
||||||
|
@ -16,6 +19,7 @@
|
||||||
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
|
||||||
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
|
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
|
||||||
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
|
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
|
||||||
|
"mix_audit": {:hex, :mix_audit, "1.0.1", "9dd114408961b8db214f42fee40b2f632ecd7e4fd29500403068c82c77db8361", [:make, :mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.8.0", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "65066bb7757078aa49faaa2f7c1e2d52f56ff6fe6cff01723dbaf5be2a75771b"},
|
||||||
"mustache": {:hex, :mustache, "0.3.1", "4c6ee79b13aae954035fe31b83c94480ddc7b536d09c44d4c65e61a9ead38d6b", [:mix], [], "hexpm", "8dc92b9b92a0d7449628f4fc981f8018a16a5b8c9907249e59db461482dac143"},
|
"mustache": {:hex, :mustache, "0.3.1", "4c6ee79b13aae954035fe31b83c94480ddc7b536d09c44d4c65e61a9ead38d6b", [:mix], [], "hexpm", "8dc92b9b92a0d7449628f4fc981f8018a16a5b8c9907249e59db461482dac143"},
|
||||||
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
|
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
|
||||||
"phoenix_view": {:hex, :phoenix_view, "1.0.0", "fea71ecaaed71178b26dd65c401607de5ec22e2e9ef141389c721b3f3d4d8011", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "82be3e2516f5633220246e2e58181282c71640dab7afc04f70ad94253025db0c"},
|
"phoenix_view": {:hex, :phoenix_view, "1.0.0", "fea71ecaaed71178b26dd65c401607de5ec22e2e9ef141389c721b3f3d4d8011", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "82be3e2516f5633220246e2e58181282c71640dab7afc04f70ad94253025db0c"},
|
||||||
|
@ -30,4 +34,6 @@
|
||||||
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
|
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
|
||||||
"telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"},
|
"telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"},
|
||||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||||
|
"yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"},
|
||||||
|
"yaml_elixir": {:hex, :yaml_elixir, "2.8.0", "c7ff0034daf57279c2ce902788ce6fdb2445532eb4317e8df4b044209fae6832", [:mix], [{:yamerl, "~> 0.8", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "4b674bd881e373d1ac6a790c64b2ecb69d1fd612c2af3b22de1619c15473830b"},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue