From 84caea3af20fb5aff0ad0913baed38104b260aac Mon Sep 17 00:00:00 2001
From: mithereal <mithereal@gmail.com>
Date: Sat, 17 Sep 2022 12:09:04 -0700
Subject: [PATCH] refactor

---
 .credo.exs                         | 209 +++++++++++++++++++++++++++++
 config/config.exs                  |   2 -
 lib/farside.ex                     |  82 +++++------
 lib/farside/application.ex         |  13 +-
 lib/farside/deadcheck.ex           |   6 +-
 lib/farside/healthycheck.ex        |  18 +--
 lib/farside/http.ex                |  11 +-
 lib/farside/instance.ex            |  12 +-
 lib/farside/instance.supervisor.ex |   6 +-
 lib/farside/last_updated.ex        |   2 +
 lib/farside/service.ex             | 158 ++++++++++++----------
 lib/farside/service.supervisor.ex  |   5 +
 lib/farside/throttle.ex            |   2 +
 lib/farside/unhealthycheck.ex      |   6 +-
 lib/service.ex                     |   2 +
 mix.exs                            |   2 +
 mix.lock                           |   6 +
 17 files changed, 402 insertions(+), 140 deletions(-)
 create mode 100644 .credo.exs

diff --git a/.credo.exs b/.credo.exs
new file mode 100644
index 0000000..305e323
--- /dev/null
+++ b/.credo.exs
@@ -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`.
+        #
+      }
+    }
+  ]
+}
diff --git a/config/config.exs b/config/config.exs
index 970aae1..50a8eb7 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -1,8 +1,6 @@
 import Config
 
 config :farside,
-  update_file: ".update-results",
-  service_prefix: "service-",
   index: "index.eex",
   route: "route.eex",
   headers: [
diff --git a/lib/farside.ex b/lib/farside.ex
index 7d7b8ea..22bc8f6 100644
--- a/lib/farside.ex
+++ b/lib/farside.ex
@@ -1,9 +1,13 @@
 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/
   @reddit_regex ~r/reddit.com|libreddit|teddit/
   @instagram_regex ~r/instagram.com|bibliogram/
@@ -35,42 +39,40 @@ defmodule Farside do
   alias Farside.LastUpdated
 
   def get_services_map do
-    services_map =
-      Farside.Instance.Supervisor.list()
-      |> Enum.map(fn service ->
-        data = :ets.lookup(String.to_atom(service), :default) |> List.first()
+    Farside.Instance.Supervisor.list()
+    |> Enum.map(fn service ->
+      data = :ets.lookup(String.to_atom(service), :default) |> List.first()
 
-        instances =
-          case is_nil(data) do
-            true ->
-              []
+      case is_nil(data) do
+        true ->
+          []
 
-            false ->
-              {_, service} = data
+        false ->
+          {_, service} = data
 
-              registry = "#{service.type}_healthy"
+          registry = "#{service.type}_healthy"
 
-              instances =
-                for instance <- service.instances do
-                  matches = Registry.match(:status, registry, instance)
+          instances =
+            for instance <- service.instances do
+              matches = Registry.match(:status, registry, instance)
 
-                  {_, instance} =
-                    case Enum.count(matches) > 0 do
-                      true -> List.first(matches)
-                      false -> {:error, nil}
-                    end
-
-                  instance
+              {_, instance} =
+                case Enum.count(matches) > 0 do
+                  true -> List.first(matches)
+                  false -> {:error, nil}
                 end
-                |> Enum.reject(fn x -> x == nil end)
 
-              Map.put(
-                service,
-                :instances,
-                instances
-              )
-          end
-      end)
+              instance
+            end
+            |> Enum.reject(fn x -> x == nil end)
+
+          Map.put(
+            service,
+            :instances,
+            instances
+          )
+      end
+    end)
   end
 
   def get_service(service) do
@@ -149,18 +151,4 @@ defmodule Farside do
         instance
     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
diff --git a/lib/farside/application.ex b/lib/farside/application.ex
index b57d253..3801e16 100644
--- a/lib/farside/application.ex
+++ b/lib/farside/application.ex
@@ -78,7 +78,18 @@ defmodule Farside.Application do
 
       struct(%Service{}, service_atom)
       |> 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
 
     response
diff --git a/lib/farside/deadcheck.ex b/lib/farside/deadcheck.ex
index 1494acc..8d38040 100644
--- a/lib/farside/deadcheck.ex
+++ b/lib/farside/deadcheck.ex
@@ -5,6 +5,8 @@ defmodule Farside.Server.DeadCheck do
   use Task
   alias Farside.LastUpdated
 
+  require Logger
+
   def child_spec(args) do
     %{
       id: __MODULE__,
@@ -20,7 +22,7 @@ defmodule Farside.Server.DeadCheck do
   def poll() do
     receive do
     after
-      1_200_000 ->
+      86_400_000 ->
         run()
         poll()
     end
@@ -29,6 +31,8 @@ defmodule Farside.Server.DeadCheck do
   def run() do
     LastUpdated.value(DateTime.utc_now())
 
+    Logger.info("Dead Service Check Running")
+
     Registry.dispatch(:status, "dead", fn entries ->
       for {pid, _} <- entries, do: GenServer.cast(pid, :check)
     end)
diff --git a/lib/farside/healthycheck.ex b/lib/farside/healthycheck.ex
index 50fae45..240b2aa 100644
--- a/lib/farside/healthycheck.ex
+++ b/lib/farside/healthycheck.ex
@@ -5,6 +5,8 @@ defmodule Farside.Server.HealthyCheck do
   use Task
   alias Farside.LastUpdated
 
+  require Logger
+
   def child_spec(args) do
     %{
       id: __MODULE__,
@@ -20,27 +22,19 @@ defmodule Farside.Server.HealthyCheck do
   def poll() do
     receive do
     after
-      90_000 ->
+      300_000 ->
         run()
         poll()
     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
     LastUpdated.value(DateTime.utc_now())
 
+    Logger.info("Healthy Service Check Running")
+
     Registry.dispatch(:status, "healthy", fn entries ->
-      for {pid, url} <- entries do
+      for {pid, _url} <- entries do
         GenServer.cast(pid, :check)
       end
     end)
diff --git a/lib/farside/http.ex b/lib/farside/http.ex
index e30d1c1..9f70722 100644
--- a/lib/farside/http.ex
+++ b/lib/farside/http.ex
@@ -1,6 +1,11 @@
 defmodule Farside.Http do
   require Logger
 
+  @moduledoc """
+  Http
+    the http client
+  """
+
   @headers Application.fetch_env!(:farside, :headers)
   @queries Application.fetch_env!(:farside, :queries)
   @recv_timeout String.to_integer(Application.fetch_env!(:farside, :recv_timeout))
@@ -108,11 +113,11 @@ defmodule Farside.Http do
           nil
       end
 
-    unless is_nil(data) do
+    if is_nil(data) do
+      :bad
+    else
       {_test_url, value, _service} = data
       value
-    else
-      :bad
     end
   end
 end
diff --git a/lib/farside/instance.ex b/lib/farside/instance.ex
index d0a382f..fdc9e1c 100644
--- a/lib/farside/instance.ex
+++ b/lib/farside/instance.ex
@@ -1,9 +1,12 @@
 defmodule Farside.Instance do
   use GenServer
 
-  require Logger
+  @moduledoc """
+  Instance
+    this will store the pointer to ets
+  """
 
-  alias Farside.Http
+  require Logger
 
   @registry_name :instance
 
@@ -15,6 +18,7 @@ defmodule Farside.Instance do
     }
   end
 
+  @impl true
   def init(init_arg) do
     ref =
       :ets.new(String.to_atom(init_arg.type), [
@@ -40,6 +44,7 @@ defmodule Farside.Instance do
     GenServer.call(__MODULE__, :shutdown)
   end
 
+  @impl true
   def handle_call(
         :shutdown,
         _from,
@@ -48,6 +53,7 @@ defmodule Farside.Instance do
     {:stop, {:ok, "Normal Shutdown"}, state}
   end
 
+  @impl true
   def handle_cast(
         :shutdown,
         state
@@ -61,7 +67,7 @@ defmodule Farside.Instance do
   end
 
   @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)
     {:noreply, {names, refs}}
   end
diff --git a/lib/farside/instance.supervisor.ex b/lib/farside/instance.supervisor.ex
index c053f5a..7bff19b 100644
--- a/lib/farside/instance.supervisor.ex
+++ b/lib/farside/instance.supervisor.ex
@@ -1,7 +1,11 @@
 defmodule Farside.Instance.Supervisor do
   use DynamicSupervisor
 
-  alias __MODULE__, as: SUPERVISOR
+  @moduledoc """
+  Instance Supervisor
+    this will supervise the instance
+  """
+
   alias Farside.Instance, as: SERVER
 
   @name :instance_supervisor
diff --git a/lib/farside/last_updated.ex b/lib/farside/last_updated.ex
index 6cf83a9..bc4cd2c 100644
--- a/lib/farside/last_updated.ex
+++ b/lib/farside/last_updated.ex
@@ -1,6 +1,8 @@
 defmodule Farside.LastUpdated do
   use Agent
 
+  @moduledoc nil
+
   def start_link(initial_value) do
     Agent.start_link(fn -> initial_value end, name: __MODULE__)
   end
diff --git a/lib/farside/service.ex b/lib/farside/service.ex
index eaee103..409cc4b 100644
--- a/lib/farside/service.ex
+++ b/lib/farside/service.ex
@@ -1,6 +1,11 @@
 defmodule Farside.Service do
   use GenServer
 
+  @moduledoc """
+  Service
+    this will store the service state
+  """
+
   require Logger
 
   alias Farside.Http
@@ -21,19 +26,22 @@ defmodule Farside.Service do
     }
   end
 
+  @impl true
   def init(data) do
     initial_state = %__MODULE__{
       url: data.url,
       type: data.type,
       test_url: data.test_url,
-      last_update: nil,
+      last_update:
+        DateTime.utc_now()
+        |> DateTime.add(-86_400, :second),
       status: []
     }
 
-    healthy = "#{data.type}_healthy"
+    unhealthy = "#{data.type}_unhealthy"
 
-    Registry.register(:status, healthy, data.url)
-    Registry.register(:status, "healthy", data.url)
+    Registry.register(:status, unhealthy, data.url)
+    Registry.register(:status, "unhealthy", data.url)
     {:ok, initial_state}
   end
 
@@ -46,6 +54,7 @@ defmodule Farside.Service do
     GenServer.call(__MODULE__, :shutdown)
   end
 
+  @impl true
   def handle_call(
         :shutdown,
         _from,
@@ -54,28 +63,6 @@ defmodule Farside.Service do
     {:stop, {:ok, "Normal Shutdown"}, state}
   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
   def handle_cast(:load, state) do
     reply = Http.test_service(state)
@@ -91,57 +78,90 @@ defmodule Farside.Service do
 
   @impl true
   def handle_cast(:check, state) do
-    reply = Http.test_service(state)
-
-    status = state.status ++ [reply]
-
-    max_queue = Application.get_env(:farside, :max_fail_rate, 50) + 5
-
-    status =
-      case Enum.count(status) < max_queue do
-        true -> status
-        false -> []
-      end
-
-    state = %{state | status: status}
-
-    state = %{state | last_update: DateTime.utc_now()}
-
-    healthy = "#{state.type}_healthy"
-    unhealthy = "#{state.type}_unhealthy"
-    dead = "#{state.type}_dead"
-
-    Registry.unregister_match(:status, "healthy", state.url)
-    Registry.unregister_match(:status, "unhealthy", state.url)
-    Registry.unregister_match(:status, "dead", state.url)
-
-    Registry.unregister_match(:status, healthy, state.url)
-    Registry.unregister_match(:status, unhealthy, state.url)
-    Registry.unregister_match(:status, dead, state.url)
+    dt =
+      DateTime.utc_now()
+      |> DateTime.add(-60, :second)
 
     state =
-      if reply != :good do
-        filtered = Enum.reject(status, fn x -> x == :good end)
+      case DateTime.compare(dt, state.last_update) do
+        :gt ->
+          reply = Http.test_service(state)
 
-        fails_before_death = Application.get_env(:farside, :max_fail_rate, 50)
+          status = state.status ++ [reply]
 
-        case Enum.count(filtered) < fails_before_death do
-          true ->
-            Registry.register(:status, "unhealthy", state.url)
-            Registry.register(:status, unhealthy, state.url)
+          max_queue = Application.get_env(:farside, :max_fail_rate, 50) + 5
+
+          status =
+            case Enum.count(status) < max_queue do
+              true -> status
+              false -> []
+            end
+
+          state = %{state | status: status}
+
+          state = %{state | last_update: DateTime.utc_now()}
+
+          healthy = "#{state.type}_healthy"
+          unhealthy = "#{state.type}_unhealthy"
+          dead = "#{state.type}_dead"
+
+          Registry.unregister_match(:status, "healthy", state.url)
+          Registry.unregister_match(:status, "unhealthy", state.url)
+          Registry.unregister_match(:status, "dead", state.url)
+
+          Registry.unregister_match(:status, healthy, state.url)
+          Registry.unregister_match(:status, unhealthy, state.url)
+          Registry.unregister_match(:status, dead, state.url)
+
+          if reply != :good do
+            filtered = Enum.reject(status, fn x -> x == :good end)
+
+            fails_before_death = Application.get_env(:farside, :max_fail_rate, 50)
+
+            case Enum.count(filtered) < fails_before_death do
+              true ->
+                Registry.register(:status, "unhealthy", state.url)
+                Registry.register(:status, unhealthy, state.url)
+                state
+
+              false ->
+                Registry.register(:status, "dead", state.url)
+                Registry.register(:status, dead, state.url)
+                %{state | status: [:bad]}
+            end
+          else
+            Registry.register(:status, "healthy", state.url)
+            Registry.register(:status, healthy, state.url)
             state
+          end
 
-          false ->
-            Registry.register(:status, "dead", state.url)
-            Registry.register(:status, dead, state.url)
-            %{state | status: [:bad]}
-        end
-      else
-        Registry.register(:status, "healthy", state.url)
-        Registry.register(:status, healthy, state.url)
-        state
+        _ ->
+          %{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}
+  end
 end
diff --git a/lib/farside/service.supervisor.ex b/lib/farside/service.supervisor.ex
index 85369e0..4f73703 100644
--- a/lib/farside/service.supervisor.ex
+++ b/lib/farside/service.supervisor.ex
@@ -1,6 +1,11 @@
 defmodule Farside.Service.Supervisor do
   use DynamicSupervisor
 
+  @moduledoc """
+  Service Supervisor
+    this will supervise the service
+  """
+
   alias __MODULE__, as: SUPERVISOR
   alias Farside.Service, as: SERVER
 
diff --git a/lib/farside/throttle.ex b/lib/farside/throttle.ex
index e2561ab..77515a1 100644
--- a/lib/farside/throttle.ex
+++ b/lib/farside/throttle.ex
@@ -2,6 +2,8 @@ defmodule Farside.Throttle do
   import Plug.Conn
   use PlugAttack
 
+  @moduledoc nil
+
   rule "throttle per ip", conn do
     # throttle to 1 request per second
     throttle(conn.remote_ip,
diff --git a/lib/farside/unhealthycheck.ex b/lib/farside/unhealthycheck.ex
index 05a8f1f..67a1fa1 100644
--- a/lib/farside/unhealthycheck.ex
+++ b/lib/farside/unhealthycheck.ex
@@ -5,6 +5,8 @@ defmodule Farside.Server.UnHealthyCheck do
   use Task
   alias Farside.LastUpdated
 
+  require Logger
+
   def child_spec(args) do
     %{
       id: __MODULE__,
@@ -20,7 +22,7 @@ defmodule Farside.Server.UnHealthyCheck do
   def poll() do
     receive do
     after
-      120_000 ->
+      200_000 ->
         run()
         poll()
     end
@@ -29,6 +31,8 @@ defmodule Farside.Server.UnHealthyCheck do
   def run() do
     LastUpdated.value(DateTime.utc_now())
 
+    Logger.info("Unhealthy Service Check Running")
+
     Registry.dispatch(:status, "unhealthy", fn entries ->
       for {pid, _} <- entries, do: GenServer.cast(pid, :check)
     end)
diff --git a/lib/service.ex b/lib/service.ex
index ae964f6..e0f84ce 100644
--- a/lib/service.ex
+++ b/lib/service.ex
@@ -1,4 +1,6 @@
 defmodule Service do
+  @moduledoc nil
+
   defstruct type: nil,
             test_url: nil,
             fallback: nil,
diff --git a/mix.exs b/mix.exs
index fab2e2d..c29fb8b 100644
--- a/mix.exs
+++ b/mix.exs
@@ -41,6 +41,8 @@ defmodule Farside.MixProject do
       {:jason, "~> 1.1"},
       {:plug_attack, "~> 0.4.2"},
       {: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}
     ]
   end
diff --git a/mix.lock b/mix.lock
index 02e6c7d..5ec0e05 100644
--- a/mix.lock
+++ b/mix.lock
@@ -1,13 +1,16 @@
 %{
   "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"},
+  "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"},
   "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_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"},
+  "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"},
   "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"},
+  "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
   "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"},
   "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"},
   "mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
   "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"},
   "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"},
@@ -30,4 +34,6 @@
   "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"},
   "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"},
 }