From ab4cefe72c9091cf46014f57ab1f0f0a09cbafdb Mon Sep 17 00:00:00 2001
From: Aleksei Magusev <lexmag@me.com>
Date: Mon, 27 Apr 2020 23:43:32 +0200
Subject: [PATCH] Ensure start options take precedence

---
 CHANGELOG.md   | 13 ++++++++-----
 lib/fluxter.ex | 45 +++++++++++++++++++++++++++++++--------------
 2 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e137675..3713fd7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,12 +1,15 @@
 # Changelog
 
+  * Fixed prefix building when start options provided.
+  * Dropped support for Elixir v1.2.
+
 ## v0.8.1
 
   * Fixed port command for OTP versions that support ancillary data sending.
 
 ## v0.8.0
 
-  * Added support for module, function, arguments tuple in `Fluxter.measure/4`.
+  * Added support for module, function, arguments tuple in `measure/4`.
 
 ## v0.7.1
 
@@ -14,17 +17,17 @@
 
 ## v0.7.0
 
-  * Added the `Fluxter.start_link/1` callback to support runtime configuration.
+  * Added the `c:Fluxter.start_link/1` callback to support runtime configuration.
 
 __Deprecations:__
 
-  * Passing child specification options to `Fluxter.child_spec/1` is deprecated.
+  * Passing child specification options to `child_spec/1` is deprecated.
 
 ## v0.6.1
 
-  * Fixed a bug in the `Fluxter.child_spec/1` callback.
+  * Fixed a bug in the `c:Fluxter.child_spec/1` callback.
 
 ## v0.6.0
 
-  * Added the `Fluxter.child_spec/1` callback.
+  * Added the `c:Fluxter.child_spec/1` callback.
   * Started flushing counters synchronously when calling `Fluxter.flush_counter/1`.
diff --git a/lib/fluxter.ex b/lib/fluxter.ex
index 9e45f00..ddc2aab 100644
--- a/lib/fluxter.ex
+++ b/lib/fluxter.ex
@@ -307,11 +307,15 @@ defmodule Fluxter do
       def start_link(options \\ []) do
         import Supervisor.Spec
 
-        {host, port, prefix} = Fluxter.load_config(__MODULE__, options)
-        conn = Fluxter.Conn.new(host, port)
-        conn = %{conn | header: [conn.header | prefix]}
+        config = Fluxter.get_config(__MODULE__, options)
 
-        Enum.map(@worker_names, &worker(Fluxter.Conn, [conn, &1], id: &1))
+        conn =
+          config.host
+          |> Fluxter.Conn.new(config.port)
+          |> Map.update!(:header, &[&1 | config.prefix])
+
+        @worker_names
+        |> Enum.map(&worker(Fluxter.Conn, [conn, &1], id: &1))
         |> Supervisor.start_link(strategy: :one_for_one)
       end
 
@@ -325,7 +329,8 @@ defmodule Fluxter do
       def write(measurement, tags \\ [], fields)
 
       def write(measurement, tags, fields) when is_list(fields) do
-        System.unique_integer([:positive])
+        [:positive]
+        |> System.unique_integer()
         |> rem(@pool_size)
         |> worker_name()
         |> Fluxter.Conn.write(measurement, tags, fields)
@@ -366,19 +371,31 @@ defmodule Fluxter do
   end
 
   @doc false
-  def load_config(module, options) do
-    {loc_env, glob_env} =
-      Application.get_all_env(:fluxter)
+  def get_config(module, overrides) do
+    {module_env, global_env} =
+      :fluxter
+      |> Application.get_all_env()
       |> Keyword.pop(module, [])
 
-    host = options[:host] || loc_env[:host] || glob_env[:host]
-    port = options[:port] || loc_env[:port] || glob_env[:port]
-    prefix = build_prefix(glob_env[:prefix], loc_env[:prefix], options[:prefix])
+    env = module_env ++ global_env
+    options = overrides ++ env
 
-    {host, port, prefix}
+    %{
+      prefix: build_prefix(env, overrides),
+      host: Keyword.get(options, :host, "127.0.0.1"),
+      port: Keyword.get(options, :port, 8125)
+    }
   end
 
-  defp build_prefix(part1, part2, part3) do
-    Enum.map_join([part1, part2, part3], &(&1 && [&1, ?_]))
+  defp build_prefix(env, overrides) do
+    case Keyword.fetch(overrides, :prefix) do
+      {:ok, prefix} ->
+        [prefix, ?_]
+
+      :error ->
+        env
+        |> Keyword.get_values(:prefix)
+        |> Enum.map_join(&(&1 && [&1, ?_]))
+    end
   end
 end