Skip to content

Commit f7c21d3

Browse files
author
Stuart Eccles
committed
Merge branch 'master' of github.com:stueccles/analytics-elixir
2 parents 5b1d343 + 7e11778 commit f7c21d3

6 files changed

Lines changed: 68 additions & 31 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ segment-*.tar
2525
.DS_Store
2626
.formatter.exs
2727
.vscode/
28-
28+
.elixir_ls/

lib/segment.ex

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -155,25 +155,29 @@ defmodule Segment do
155155
| Segment.Analytics.Alias.t()
156156
| Segment.Analytics.Group.t()
157157
| Segment.Analytics.Page.t()
158-
require Logger
159-
@service Application.get_env(:segment, :sender_impl, Segment.Analytics.Batcher)
160158

161159
@doc """
162160
Start the configured GenServer for handling Segment events with the Segment HTTP Source API Write Key
163161
164162
By default if nothing is configured it will start `Segment.Analytics.Batcher`
165163
"""
166164
@spec start_link(String.t()) :: GenServer.on_start()
167-
defdelegate start_link(api_key), to: @service
165+
def start_link(api_key) do
166+
Segment.Config.service().start_link(api_key)
167+
end
168168

169169
@doc """
170170
Start the configured GenServer for handling Segment events with the Segment HTTP Source API Write Key and a custom Tesla Adapter.
171171
172172
By default if nothing is configured it will start `Segment.Analytics.Batcher`
173173
"""
174174
@spec start_link(String.t(), Telsa.adapter()) :: GenServer.on_start()
175-
defdelegate start_link(api_key, adapter), to: @service
175+
def start_link(api_key, adapter) do
176+
Segment.Config.service().start_link(api_key, adapter)
177+
end
176178

177179
@spec child_spec(map()) :: map()
178-
defdelegate child_spec(opts), to: @service
180+
def child_spec(opts) do
181+
Segment.Config.service().child_spec(opts)
182+
end
179183
end

lib/segment/analytics.ex

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ defmodule Segment.Analytics do
1212

1313
@type segment_id :: String.t() | integer()
1414

15-
@service Application.get_env(:segment, :sender_impl, Segment.Analytics.Batcher)
16-
1715
@doc """
1816
Make a call to Segment with an event. Should be of type `Track, Identify, Screen, Alias, Group or Page`
1917
"""
@@ -165,5 +163,7 @@ defmodule Segment.Analytics do
165163
end
166164

167165
@spec call(Segment.segment_event()) :: :ok
168-
defdelegate call(event), to: @service
166+
def call(event) do
167+
Segment.Config.service().call(event)
168+
end
169169
end

lib/segment/batcher.ex

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,6 @@ defmodule Segment.Analytics.Batcher do
2222
use GenServer
2323
alias Segment.Analytics.{Track, Identify, Screen, Alias, Group, Page}
2424

25-
@max_batch_size Application.get_env(:segment, :max_batch_size, 100)
26-
@batch_every_ms Application.get_env(:segment, :batch_every_ms, 2000)
27-
2825
@doc """
2926
Start the `Segment.Analytics.Batcher` GenServer with an Segment HTTP Source API Write Key
3027
"""
@@ -96,7 +93,7 @@ defmodule Segment.Analytics.Batcher do
9693

9794
# Helpers
9895
defp schedule_batch_send do
99-
Process.send_after(self(), :process_batch, @batch_every_ms)
96+
Process.send_after(self(), :process_batch, Segment.Config.batch_every_ms())
10097
end
10198

10299
defp enqueue(event) do
@@ -106,13 +103,16 @@ defmodule Segment.Analytics.Batcher do
106103
defp extract_batch(queue, 0),
107104
do: {[], queue}
108105

109-
defp extract_batch(queue, length) when length >= @max_batch_size do
110-
:queue.split(@max_batch_size, queue)
111-
|> split_result()
112-
end
106+
defp extract_batch(queue, length) do
107+
max_batch_size = Segment.Config.max_batch_size()
113108

114-
defp extract_batch(queue, length),
115-
do: :queue.split(length, queue) |> split_result()
109+
if length >= max_batch_size do
110+
:queue.split(max_batch_size, queue)
111+
|> split_result()
112+
else
113+
:queue.split(length, queue) |> split_result()
114+
end
115+
end
116116

117117
defp split_result({q1, q2}), do: {:queue.to_list(q1), q2}
118118
end

lib/segment/client/http.ex

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,18 +41,14 @@ defmodule Segment.Http do
4141
use Retry
4242

4343
@segment_api_url "https://api.segment.io/v1/"
44-
@send_to_http Application.get_env(:segment, :send_to_http, true)
45-
@retry_attempts Application.get_env(:segment, :retry_attempts, 3)
46-
@retry_expiry Application.get_env(:segment, :retry_expiry, 10_000)
47-
@retry_start Application.get_env(:segment, :retry_start, 100)
4844

4945
@doc """
5046
Create a Tesla client with the Segment Source Write API Key
5147
"""
5248
@spec client(String.t()) :: client()
5349
def client(api_key) do
5450
adapter =
55-
case @send_to_http do
51+
case Segment.Config.send_to_http() do
5652
true ->
5753
Application.get_env(:segment, :tesla)[:adapter] ||
5854
{Tesla.Adapter.Hackney, [recv_timeout: 30_000]}
@@ -89,7 +85,7 @@ defmodule Segment.Http do
8985
"""
9086
@spec send(String.t(), Segment.segment_event()) :: :ok | :error
9187
def send(client, event) do
92-
case make_request(client, event.type, prepare_events(event), @retry_attempts) do
88+
case make_request(client, event.type, prepare_events(event), Segment.Config.retry_attempts()) do
9389
{:ok, %{status: status}} when status == 200 ->
9490
:ok
9591

@@ -98,7 +94,10 @@ defmodule Segment.Http do
9894
:error
9995

10096
{:error, err} ->
101-
Logger.error("[Segment] Call Failed after #{@retry_attempts} retries. #{inspect(err)}")
97+
Logger.error(
98+
"[Segment] Call Failed after #{Segment.Config.retry_attempts()} retries. #{inspect(err)}"
99+
)
100+
102101
:error
103102

104103
err ->
@@ -120,7 +119,7 @@ defmodule Segment.Http do
120119
|> add_if(:context, context)
121120
|> add_if(:integrations, integrations)
122121

123-
case make_request(client, "batch", data, @retry_attempts) do
122+
case make_request(client, "batch", data, Segment.Config.retry_attempts()) do
124123
{:ok, %{status: status}} when status == 200 ->
125124
:ok
126125

@@ -133,9 +132,9 @@ defmodule Segment.Http do
133132

134133
{:error, err} ->
135134
Logger.error(
136-
"[Segment] Batch call of #{length(events)} events failed after #{@retry_attempts} retries. #{
137-
inspect(err)
138-
}"
135+
"[Segment] Batch call of #{length(events)} events failed after #{
136+
Segment.Config.retry_attempts()
137+
} retries. #{inspect(err)}"
139138
)
140139

141140
:error
@@ -147,7 +146,10 @@ defmodule Segment.Http do
147146
end
148147

149148
defp make_request(client, url, data, retries) when retries > 0 do
150-
retry with: linear_backoff(@retry_start, 2) |> cap(@retry_expiry) |> Stream.take(retries) do
149+
retry with:
150+
linear_backoff(Segment.Config.retry_start(), 2)
151+
|> cap(Segment.Config.retry_expiry())
152+
|> Stream.take(retries) do
151153
Tesla.post(client, url, data)
152154
after
153155
result -> result

lib/segment/config.ex

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
defmodule Segment.Config do
2+
@moduledoc false
3+
4+
def service do
5+
Application.get_env(:segment, :sender_impl, Segment.Analytics.Batcher)
6+
end
7+
8+
def max_batch_size() do
9+
Application.get_env(:segment, :max_batch_size, 100)
10+
end
11+
12+
def batch_every_ms() do
13+
Application.get_env(:segment, :batch_every_ms, 2000)
14+
end
15+
16+
def send_to_http() do
17+
Application.get_env(:segment, :send_to_http, true)
18+
end
19+
20+
def retry_attempts() do
21+
Application.get_env(:segment, :retry_attempts, 3)
22+
end
23+
24+
def retry_expiry() do
25+
Application.get_env(:segment, :retry_expiry, 10_000)
26+
end
27+
28+
def retry_start() do
29+
Application.get_env(:segment, :retry_start, 100)
30+
end
31+
end

0 commit comments

Comments
 (0)