Skip to content

Commit ddc2b19

Browse files
committed
Use default env, update docs
1 parent 1151db2 commit ddc2b19

File tree

7 files changed

+41
-89
lines changed

7 files changed

+41
-89
lines changed

lib/broadway.ex

+19-32
Original file line numberDiff line numberDiff line change
@@ -609,55 +609,42 @@ defmodule Broadway do
609609
610610
## Configuration Storage
611611
612-
Broadway stores configuration globally in a chosen storage method. Broadway comes with two configuration storage options:
612+
Broadway stores configuration globally in a chosen storage method.
613+
Broadway comes with two configuration storage options:
613614
614615
- `:persistent_term`, the default.
615616
- `:ets`
616617
617-
618-
619618
### Persistent Term
620619
621-
A `:persistent_term` backed configuration storage, which is the default storage option used. Configurations are not deleted when the Broadway server process goes down, so as to avoid a global GC.
620+
This is the most efficient option for static Broadway pipeline definitions,
621+
as this option never deletes the Broadway configuration from storage:
622622
623623
```elixir
624-
config Broadway, config_storage: :persistent_term
624+
config :broadway, config_storage: :persistent_term
625625
```
626626
627+
The speed of storing and updating using `:persistent_term` is proportional
628+
to the number of already-created terms in the storage. If you are creating
629+
several Broadway pipelines dynamically, that may affect the persistent term
630+
storage performance. Furthermore, even if you are restarting the same pipeline
631+
but you are using different parameters each time, that will require a global
632+
GC to update the `:persistent_term` configuration. If you are starting Broadway
633+
pipelines dynamically, you must use `:ets`.
634+
627635
### ETS
628-
An ETS-backed configuration storage. Only use this if performance improvements over the default `:persistent_term`-based storage is needed.
629636
637+
An ETS-backed configuration storage, useful if Broadway pipelines are
638+
started dynamically.
630639
To use this configuration storage option, set your application config.exs as so:
631640
632641
```elixir
633-
config Broadway, config_storage: :ets
634-
```
635-
636-
To pass options, use a tuple with a keyword list as so:
637-
638-
```elixir
639-
config Broadway,
640-
config_storage: :ets,
641-
config_storage_opts: [
642-
table_name: :my_table
643-
]
642+
config :broadway, config_storage: :ets
644643
```
645644
646-
Accepted options:
647-
- `:table_name` - configure the table name. Defaults to `:broadway_configs`.
648-
649-
#### Performance Improvements over `:persistent_term`
650-
`:persistent_term` will trigger a global GC on each `put` or `erase`. For situations where there are a large number of dynamically created Broadway pipelines that are created or removed, this may result in the global GC being triggered multiple times. If there is a large number of processes, this may cause the system to be less responsive until all heaps have been scanned.
651-
652-
As `Broadway.ConfigStorage.PersistentTerm` does not perform an erase when the Broadway server process goes down, it may result in memory buildup over time within the `:persistent_term` hash table, especially when dynamic names are used for the Broadway servers.
653-
654-
Furthermore, the speed of storing and updating using `:persistent_term` is proportional to the number of already-created terms in the hash table, as the hash table (and term) is copied.
655-
656-
Using `:ets` as the config storage will allow for a large number of Broadway server configurations to be stored and fetched without the associated performance tradeoffs that `:persistent_term` has.
657-
658-
659-
660-
645+
Using `:ets` as the config storage will allow for a dynamic number of Broadway server
646+
configurations to be stored and fetched without the associated performance tradeoffs
647+
that `:persistent_term` has.
661648
662649
## Telemetry
663650

lib/broadway/config_storage.ex

+1-10
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,10 @@ defmodule Broadway.ConfigStorage do
3434
"""
3535
@spec get_module() :: module()
3636
def get_module() do
37-
Application.get_env(Broadway, :config_storage, :persistent_term)
38-
|> case do
37+
case Application.fetch_env!(:broadway, :config_storage) do
3938
:ets -> Ets
4039
:persistent_term -> PersistentTerm
4140
mod -> mod
4241
end
4342
end
44-
45-
@doc """
46-
Retrieves any options set on the `:config_storage` key.
47-
"""
48-
@spec get_options() :: keyword()
49-
def get_options() do
50-
Application.get_env(Broadway, :config_storage_opts) || []
51-
end
5243
end

lib/broadway/config_storage/ets.ex

+7-15
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
defmodule Broadway.ConfigStorage.Ets do
22
@moduledoc false
3-
alias Broadway.ConfigStorage
4-
@behaviour ConfigStorage
3+
@behaviour Broadway.ConfigStorage
54

6-
@default_table :broadway_configs
5+
def table(), do: __MODULE__
76

8-
def default_table(), do: @default_table
9-
10-
@impl ConfigStorage
7+
@impl true
118
def setup do
129
if :undefined == :ets.whereis(table()) do
1310
:ets.new(table(), [:named_table, :public, :set, {:read_concurrency, true}])
@@ -16,31 +13,26 @@ defmodule Broadway.ConfigStorage.Ets do
1613
:ok
1714
end
1815

19-
@impl ConfigStorage
16+
@impl true
2017
def list do
2118
:ets.select(table(), [{{:"$1", :_}, [], [:"$1"]}])
2219
end
2320

24-
@impl ConfigStorage
21+
@impl true
2522
def get(server) do
2623
case :ets.match(table(), {server, :"$1"}) do
2724
[[topology]] -> topology
2825
_ -> nil
2926
end
3027
end
3128

32-
@impl ConfigStorage
29+
@impl true
3330
def put(server, topology) do
3431
:ets.insert(table(), {server, topology})
3532
end
3633

37-
@impl ConfigStorage
34+
@impl true
3835
def delete(server) do
3936
:ets.delete(table(), server)
4037
end
41-
42-
defp table() do
43-
opts = ConfigStorage.get_options()
44-
Keyword.get(opts, :table_name, @default_table)
45-
end
4638
end

lib/broadway/config_storage/persistent_term.ex

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ defmodule Broadway.ConfigStorage.PersistentTerm do
22
@moduledoc false
33
@behaviour Broadway.ConfigStorage
44

5-
@impl Broadway.ConfigStorage
5+
@impl true
66
def setup do
77
unless Code.ensure_loaded?(:persistent_term) do
88
require Logger
@@ -13,24 +13,24 @@ defmodule Broadway.ConfigStorage.PersistentTerm do
1313
:ok
1414
end
1515

16-
@impl Broadway.ConfigStorage
16+
@impl true
1717
def list do
1818
for {{Broadway, name}, %Broadway.Topology{}} <- :persistent_term.get() do
1919
name
2020
end
2121
end
2222

23-
@impl Broadway.ConfigStorage
23+
@impl true
2424
def get(server) do
2525
:persistent_term.get({Broadway, server}, nil)
2626
end
2727

28-
@impl Broadway.ConfigStorage
28+
@impl true
2929
def put(server, topology) do
3030
:persistent_term.put({Broadway, server}, topology)
3131
end
3232

33-
@impl Broadway.ConfigStorage
33+
@impl true
3434
def delete(_server) do
3535
# We don't delete from persistent term on purpose. Since the process is
3636
# named, we can assume it does not start dynamically, so it will either

lib/broadway/producer.ex

+2-5
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,8 @@ defmodule Broadway.Producer do
1919
2020
If `options` is a keyword list, Broadway injects a `:broadway` option
2121
into such keyword list. This option contains the configuration for the
22-
complete Broadway topology (see `Broadway.start_link/2`. For example, you can use
23-
`options[:broadway][:name]` to uniquely identify the topology,
24-
allowing you to write terms to things such as
25-
[`:persistent_term`](https://erlang.org/doc/man/persistent_term.html)
26-
or ETS tables.
22+
complete Broadway topology (see `Broadway.start_link/2`. For example,
23+
you can use `options[:broadway][:name]` to uniquely identify the topology.
2724
2825
The `:broadway` configuration also has an `:index` key. This
2926
is the index of the producer in its supervision tree (starting

mix.exs

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ defmodule Broadway.MixProject do
2121

2222
def application do
2323
[
24-
extra_applications: [:logger]
24+
extra_applications: [:logger],
25+
env: [config_storage: :persistent_term]
2526
]
2627
end
2728

test/broadway/config_storage_test.exs

+5-21
Original file line numberDiff line numberDiff line change
@@ -3,38 +3,22 @@ defmodule Broadway.ConfigStorageTest do
33
alias Broadway.ConfigStorage.Ets
44

55
setup do
6-
prev = Application.get_env(Broadway, :config_storage)
7-
prev_opts = Application.get_env(Broadway, :config_storage_opts)
6+
prev = Application.fetch_env!(:broadway, :config_storage)
87

98
on_exit(fn ->
10-
Application.put_env(Broadway, :config_storage, prev)
11-
Application.put_env(Broadway, :config_storage_opts, prev_opts)
9+
Application.put_env(:broadway, :config_storage, prev)
1210
end)
1311
end
1412

1513
test "ets default options" do
16-
Application.put_env(Broadway, :config_storage, :ets)
14+
Application.put_env(:broadway, :config_storage, :ets)
1715
Ets.setup()
1816
assert [] = Ets.list()
1917
assert Ets.put("some name", %Broadway.Topology{})
2018
assert ["some name"] = Ets.list()
2119
assert %Broadway.Topology{} = Ets.get("some name")
22-
assert :ets.info(Ets.default_table(), :size) == 1
20+
assert :ets.info(Ets.table(), :size) == 1
2321
Ets.delete("some name")
24-
assert :ets.info(Ets.default_table(), :size) == 0
25-
end
26-
27-
test "ets custom name" do
28-
Application.put_env(Broadway, :config_storage, :ets)
29-
Application.put_env(Broadway, :config_storage_opts, table_name: :my_table)
30-
Ets.setup()
31-
assert :ets.info(:my_table, :size) == 0
32-
assert [] = Ets.list()
33-
assert Ets.put("some name", %Broadway.Topology{})
34-
assert ["some name"] = Ets.list()
35-
assert %Broadway.Topology{} = Ets.get("some name")
36-
assert :ets.info(:my_table, :size) == 1
37-
Ets.delete("some name")
38-
assert :ets.info(:my_table, :size) == 0
22+
assert :ets.info(Ets.table(), :size) == 0
3923
end
4024
end

0 commit comments

Comments
 (0)