Skip to content

Commit

Permalink
feat: provides repeated event protection
Browse files Browse the repository at this point in the history
  • Loading branch information
grzuy committed Sep 11, 2024
1 parent 9b63e62 commit 27e9988
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 13 deletions.
19 changes: 14 additions & 5 deletions lib/tower.ex
Original file line number Diff line number Diff line change
Expand Up @@ -426,11 +426,20 @@ defmodule Tower do
:logger.compare_levels(level1, level2) in [:gt, :eq]
end

defp report_event(%Event{} = event) do
reporters()
|> Enum.each(fn reporter ->
report_event(reporter, event)
end)
defp report_event(%Event{similarity_id: similarity_id} = event) do
Tower.Protection.seen(similarity_id)

Tower.Protection.get(similarity_id)
|> case do
1 ->
reporters()
|> Enum.each(fn reporter ->
report_event(reporter, event)
end)

amount ->
IO.puts("Ignoring repeated event with similarity_id=#{similarity_id}. Seen #{amount} times.")
end
end

defp report_event(reporter, %Event{reason: %ReportEventError{reporter: reporter}}) do
Expand Down
3 changes: 2 additions & 1 deletion lib/tower/application.ex
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ defmodule Tower.Application do
def start(_type, _args) do
Supervisor.start_link(
[
{Task.Supervisor, name: Tower.TaskSupervisor}
{Task.Supervisor, name: Tower.TaskSupervisor},
Tower.Protection
],
strategy: :one_for_one,
name: Tower.Supervisor
Expand Down
27 changes: 27 additions & 0 deletions lib/tower/protection.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
defmodule Tower.Protection do
use Agent

@empty_state %{}

def start_link(_initial_value) do
Agent.start_link(fn -> @empty_state end, name: __MODULE__)
end

def get(key) do
Agent.get(__MODULE__, fn state -> Map.get(state, key) end)
end

def seen(key) do
Agent.update(
__MODULE__,
fn state ->
{_, new_state} =
Map.get_and_update(state, key, fn current_value ->
{current_value, (current_value || 0) + 1}
end)

new_state
end
)
end
end
8 changes: 1 addition & 7 deletions test/tower_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ defmodule TowerTest do

test "protects reporters from repeated events" do
capture_log(fn ->
for _ <- 1..2 do
for _ <- 1..10 do
in_unlinked_process(fn ->
1 / 0

Check warning on line 559 in test/tower_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 25.3.2.12)

the call to //2 will fail with ArithmeticError

Check warning on line 559 in test/tower_test.exs

View workflow job for this annotation

GitHub Actions / main (1.15, 24.3.4.17)

the call to //2 will fail with ArithmeticError
end)
Expand All @@ -573,12 +573,6 @@ defmodule TowerTest do
kind: :error,
reason: %RuntimeError{message: "something else"}
},
%{
similarity_id: similarity_id,
level: :error,
kind: :error,
reason: %ArithmeticError{message: "bad argument in arithmetic expression"}
},
%{
similarity_id: similarity_id,
level: :error,
Expand Down

0 comments on commit 27e9988

Please sign in to comment.