Skip to content

Commit 66397d0

Browse files
Stuart EcclesStuart Eccles
authored andcommitted
added a flush to batcher and some doc changes
1 parent bc3a0fa commit 66397d0

6 files changed

Lines changed: 57 additions & 63 deletions

File tree

README.md

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Documentation can be be found at [https://hexdocs.pm/segment](https://hexdocs.pm
2323
## Usage
2424

2525
Start the Segment agent with your write_key from Segment for a HTTP API Server Source
26-
```
26+
```elixir
2727
Segment.start_link("YOUR_WRITE_KEY")
2828
```
2929
There are then two ways to call the different methods on the API.
@@ -36,11 +36,11 @@ queue and batch events to Segment.
3636
The other way is to drop down lower and use `Segment.Http` `send` and `batch` directly. This will require first creating a `client` with `Segment.Http.client/1`/`Segment.Http.client/2`
3737

3838
### Track
39-
```
39+
```elixir
4040
Segment.Analytics.track(user_id, event, %{property1: "", property2: ""})
4141
```
4242
or the full way using a struct with all the possible options for the track call
43-
```
43+
```elixir
4444
%Segment.Analytics.Track{ userId: "sdsds",
4545
event: "eventname",
4646
properties: %{property1: "", property2: ""}
@@ -49,59 +49,59 @@ or the full way using a struct with all the possible options for the track call
4949
```
5050

5151
### Identify
52-
```
52+
```elixir
5353
Segment.Analytics.identify(user_id, %{trait1: "", trait2: ""})
5454
```
5555
or the full way using a struct with all the possible options for the identify call
56-
```
56+
```elixir
5757
%Segment.Analytics.Identify{ userId: "sdsds",
5858
traits: %{trait1: "", trait2: ""}
5959
}
6060
|> Segment.Analytics.identify
6161
```
6262

6363
### Screen
64-
```
64+
```elixir
6565
Segment.Analytics.screen(user_id, name)
6666
```
6767
or the full way using a struct with all the possible options for the screen call
68-
```
68+
```elixir
6969
%Segment.Analytics.Screen{ userId: "sdsds",
7070
name: "dssd"
7171
}
7272
|> Segment.Analytics.screen
7373
```
7474

7575
### Alias
76-
```
76+
```elixir
7777
Segment.Analytics.alias(user_id, previous_id)
7878
```
7979
or the full way using a struct with all the possible options for the alias call
80-
```
80+
```elixir
8181
%Segment.Analytics.Alias{ userId: "sdsds",
8282
previousId: "dssd"
8383
}
8484
|> Segment.Analytics.alias
8585
```
8686

8787
### Group
88-
```
88+
```elixir
8989
Segment.Analytics.group(user_id, group_id)
9090
```
9191
or the full way using a struct with all the possible options for the group call
92-
```
92+
```elixir
9393
%Segment.Analytics.Group{ userId: "sdsds",
9494
groupId: "dssd"
9595
}
9696
|> Segment.Analytics.group
9797
```
9898

9999
### Page
100-
```
100+
```elixir
101101
Segment.Analytics.page(user_id, name)
102102
```
103103
or the full way using a struct with all the possible options for the page call
104-
```
104+
```elixir
105105
%Segment.Analytics.Page{ userId: "sdsds",
106106
name: "dssd"
107107
}
@@ -113,7 +113,7 @@ or the full way using a struct with all the possible options for the page call
113113

114114
If you want to set the Context manually you should create a `Segment.Analytics.Context` struct with `Segment.Analytics.Context.new/1`
115115

116-
```
116+
```elixir
117117
context = Segment.Analytics.Context.new(%{active: false})
118118

119119
Segment.Analytics.track(user_id, event, %{property1: "", property2: ""}, context)
@@ -138,25 +138,15 @@ This is how I add to a Phoenix project (may not be your preferred way)
138138

139139
1. Add the following to deps section of your mix.exs: `{:segment, "~> 0.2.0"}`
140140
and then `mix deps.get`
141-
2. Add segment to applications list in the Phoenix project mix.exs
142-
ie.
143-
```
144-
def application do
145-
[mod: {FormAndThread, []},
146-
applications: [:phoenix, :phoenix_html, :cowboy, :logger,
147-
:phoenix_ecto, :postgrex, :segment]]
148-
end
149-
```
150-
3. Add a config variable for your write_key (you may want to make this load from ENV)
141+
2. Add a config variable for your write_key (you may want to make this load from ENV)
151142
ie.
152-
```
143+
```elixir
153144
config :segment,
154145
write_key: "2iFFnRsCfi"
155146
```
156-
4. Start the segment agent as a child of the application in the application file under
157-
the lib directory. In the children list add:
158-
```
159-
worker(Segment, [Application.get_env(:segment, :write_key)])
147+
3. Start the Segment GenServer in the supervised children list. In `application.ex` add to the children list:
148+
```elixir
149+
{Segment, Application.get_env(:segment, :write_key)}
160150
```
161151

162152
## Running tests

lib/segment.ex

Lines changed: 19 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ defmodule Segment do
2222
## Usage
2323
2424
Start the Segment agent with your write_key from Segment for a HTTP API Server Source
25-
```
25+
```elixir
2626
Segment.start_link("YOUR_WRITE_KEY")
2727
```
2828
There are then two ways to call the different methods on the API.
@@ -35,11 +35,11 @@ defmodule Segment do
3535
The other way is to drop down lower and use `Segment.Http` `send` and `batch` directly. This will require first creating a `client` with `Segment.Http.client/1`/`Segment.Http.client/2`
3636
3737
### Track
38-
```
38+
```elixir
3939
Segment.Analytics.track(user_id, event, %{property1: "", property2: ""})
4040
```
4141
or the full way using a struct with all the possible options for the track call
42-
```
42+
```elixir
4343
%Segment.Analytics.Track{ userId: "sdsds",
4444
event: "eventname",
4545
properties: %{property1: "", property2: ""}
@@ -48,59 +48,59 @@ defmodule Segment do
4848
```
4949
5050
### Identify
51-
```
51+
```elixir
5252
Segment.Analytics.identify(user_id, %{trait1: "", trait2: ""})
5353
```
5454
or the full way using a struct with all the possible options for the identify call
55-
```
55+
```elixir
5656
%Segment.Analytics.Identify{ userId: "sdsds",
5757
traits: %{trait1: "", trait2: ""}
5858
}
5959
|> Segment.Analytics.identify
6060
```
6161
6262
### Screen
63-
```
63+
```elixir
6464
Segment.Analytics.screen(user_id, name)
6565
```
6666
or the full way using a struct with all the possible options for the screen call
67-
```
67+
```elixir
6868
%Segment.Analytics.Screen{ userId: "sdsds",
6969
name: "dssd"
7070
}
7171
|> Segment.Analytics.screen
7272
```
7373
7474
### Alias
75-
```
75+
```elixir
7676
Segment.Analytics.alias(user_id, previous_id)
7777
```
7878
or the full way using a struct with all the possible options for the alias call
79-
```
79+
```elixir
8080
%Segment.Analytics.Alias{ userId: "sdsds",
8181
previousId: "dssd"
8282
}
8383
|> Segment.Analytics.alias
8484
```
8585
8686
### Group
87-
```
87+
```elixir
8888
Segment.Analytics.group(user_id, group_id)
8989
```
9090
or the full way using a struct with all the possible options for the group call
91-
```
91+
```elixir
9292
%Segment.Analytics.Group{ userId: "sdsds",
9393
groupId: "dssd"
9494
}
9595
|> Segment.Analytics.group
9696
```
9797
9898
### Page
99-
```
99+
```elixir
100100
Segment.Analytics.page(user_id, name)
101101
```
102102
or the full way using a struct with all the possible options for the page call
103-
```
103+
```elixir
104104
%Segment.Analytics.Page{ userId: "sdsds",
105105
name: "dssd"
106106
}
@@ -112,7 +112,7 @@ defmodule Segment do
112112
113113
If you want to set the Context manually you should create a `Segment.Analytics.Context` struct with `Segment.Analytics.Context.new/1`
114114
115-
```
115+
```elixir
116116
context = Segment.Analytics.Context.new(%{active: false})
117117
118118
Segment.Analytics.track(user_id, event, %{property1: "", property2: ""}, context)
@@ -137,25 +137,15 @@ defmodule Segment do
137137
138138
1. Add the following to deps section of your mix.exs: `{:segment, "~> 0.2.0"}`
139139
and then `mix deps.get`
140-
2. Add segment to applications list in the Phoenix project mix.exs
141-
ie.
142-
```
143-
def application do
144-
[mod: {FormAndThread, []},
145-
applications: [:phoenix, :phoenix_html, :cowboy, :logger,
146-
:phoenix_ecto, :postgrex, :segment]]
147-
end
148-
```
149-
3. Add a config variable for your write_key (you may want to make this load from ENV)
140+
2. Add a config variable for your write_key (you may want to make this load from ENV)
150141
ie.
151-
```
142+
```elixir
152143
config :segment,
153144
write_key: "2iFFnRsCfi"
154145
```
155-
4. Start the segment agent as a child of the application in the application file under
156-
the lib directory. In the children list add:
157-
```
158-
worker(Segment, [Application.get_env(:segment, :write_key)])
146+
3. Start the Segment GenServer in the supervised children list. In `application.ex` add to the children list:
147+
```elixir
148+
{Segment, Application.get_env(:segment, :write_key)}
159149
```
160150
"""
161151
@type segment_event ::

lib/segment/analytics.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ defmodule Segment.Analytics do
33
The `Segment.Analytics` module is the easiest way to send Segment events and provides convenience methods for `track`, `identify,` `screen`, `alias`, `group`, and `page` calls
44
55
The functions will then delegate the call to the configured service implementation which can be changed with:
6-
```
6+
```elixir
77
config :segment, sender_impl: Segment.Analytics.Batcher,
88
```
99
By default (if no configuration is given) it will use `Segment.Analytics.Batcher` to send events in a batch periodically

lib/segment/batcher.ex

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ defmodule Segment.Analytics.Batcher do
55
send on a regular basis.
66
77
The `Segment.Analytics.Batcher` can be configured with
8-
```
8+
```elixir
99
config :segment,
1010
max_batch_size: 100,
1111
batch_every_ms: 5000
@@ -55,6 +55,14 @@ defmodule Segment.Analytics.Batcher do
5555
enqueue(event)
5656
end
5757

58+
@doc """
59+
Force the batcher to flush the queue and send all the events as a big batch (warning could exceed batch size)
60+
"""
61+
@spec flush() :: :ok
62+
def flush() do
63+
GenServer.call(__MODULE__, :flush)
64+
end
65+
5866
# GenServer Callbacks
5967

6068
@impl true
@@ -68,6 +76,13 @@ defmodule Segment.Analytics.Batcher do
6876
{:noreply, {client, :queue.in(event, queue)}}
6977
end
7078

79+
@impl true
80+
def handle_call(:flush, _from, {client, queue}) do
81+
items = :queue.to_list(queue)
82+
if length(items) > 0, do: Segment.Http.batch(client, items)
83+
{:reply, :ok, {client, :queue.new()}}
84+
end
85+
7186
@impl true
7287
def handle_info(:process_batch, {client, queue}) do
7388
length = :queue.len(queue)

lib/segment/client/http.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ defmodule Segment.Http do
1515
`Segment.Http` is the underlying implementation for making calls to the Segment HTTP API.
1616
1717
The `send/2` and `batch/4` methods can be used for sending events or batches of events to the API. The sending can be configured with
18-
```
18+
```elixir
1919
config :segment,
2020
send_to_http: true
2121
retry_attempts: 3,

test/segment_test.exs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,7 @@ defmodule SegmentTest do
3232

3333
Segment.Analytics.page("user1", "page debugging #{elem(:os.timestamp(), 2)}")
3434

35-
# wait 5 seconds for batcher
36-
Process.sleep(5000)
35+
Segment.Analytics.Batcher.flush()
3736
end
3837

3938
defp wait_random(n \\ 1000), do: Process.sleep(:rand.uniform(n))

0 commit comments

Comments
 (0)