-
-
Notifications
You must be signed in to change notification settings - Fork 207
Refactor span storage #817
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,78 +1,81 @@ | ||
| defmodule Sentry.Opentelemetry.SpanStorage do | ||
| @moduledoc false | ||
| use GenServer | ||
|
|
||
| @root_spans_table :sentry_root_spans | ||
| @child_spans_table :sentry_child_spans | ||
| @table :span_storage | ||
|
|
||
| def setup do | ||
| case :ets.whereis(@root_spans_table) do | ||
| :undefined -> | ||
| :ets.new(@root_spans_table, [:set, :public, :named_table]) | ||
| @spec start_link(keyword()) :: GenServer.on_start() | ||
| def start_link(opts \\ []) do | ||
| name = Keyword.get(opts, :name, __MODULE__) | ||
| GenServer.start_link(__MODULE__, nil, name: name) | ||
| end | ||
|
|
||
| _ -> | ||
| :ok | ||
| end | ||
| @impl true | ||
| def init(nil) do | ||
| _table = | ||
| if :ets.whereis(@table) == :undefined do | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If the table is tied to this GenServer, where would we ever have the table running without it that we need this check?
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When testing, an error is thrown because the table is already created. We do this in |
||
| :ets.new(@table, [:named_table, :public, :bag]) | ||
| end | ||
|
|
||
| case :ets.whereis(@child_spans_table) do | ||
| :undefined -> | ||
| :ets.new(@child_spans_table, [:bag, :public, :named_table]) | ||
| {:ok, :no_state} | ||
| end | ||
|
|
||
| _ -> | ||
| :ok | ||
| def store_span(span_data) when span_data.parent_span_id == nil do | ||
| case :ets.lookup(@table, {:root_span, span_data.span_id}) do | ||
| [] -> :ets.insert(@table, {{:root_span, span_data.span_id}, span_data}) | ||
| _ -> :ok | ||
| end | ||
|
|
||
| :ok | ||
| end | ||
|
|
||
| def store_span(span_data) do | ||
| if span_data.parent_span_id == nil do | ||
| :ets.insert(@root_spans_table, {span_data.span_id, span_data}) | ||
| else | ||
| :ets.insert(@child_spans_table, {span_data.parent_span_id, span_data}) | ||
| end | ||
|
|
||
| :ok | ||
| _ = :ets.insert(@table, {span_data.parent_span_id, span_data}) | ||
| end | ||
|
|
||
| def get_root_span(span_id) do | ||
| case :ets.lookup(@root_spans_table, span_id) do | ||
| [{^span_id, span}] -> span | ||
| case :ets.lookup(@table, {:root_span, span_id}) do | ||
| [{{:root_span, ^span_id}, span}] -> span | ||
| [] -> nil | ||
| end | ||
| end | ||
|
|
||
| def get_child_spans(parent_span_id) do | ||
| :ets.lookup(@child_spans_table, parent_span_id) | ||
| :ets.lookup(@table, parent_span_id) | ||
| |> Enum.map(fn {_parent_id, span} -> span end) | ||
| end | ||
|
|
||
| def update_span(span_data) do | ||
| if span_data.parent_span_id == nil do | ||
| :ets.insert(@root_spans_table, {span_data.span_id, span_data}) | ||
| case :ets.lookup(@table, {:root_span, span_data.parent_span_id}) do | ||
| [] -> | ||
| :ets.insert(@table, {{:root_span, span_data.parent_span_id}, span_data}) | ||
|
|
||
| _ -> | ||
| :ets.delete(@table, {:root_span, span_data.parent_span_id}) | ||
| :ets.insert(@table, {{:root_span, span_data.parent_span_id}, span_data}) | ||
| end | ||
| else | ||
| existing_spans = :ets.lookup(@child_spans_table, span_data.parent_span_id) | ||
|
|
||
| :ets.delete(@child_spans_table, span_data.parent_span_id) | ||
| existing_spans = :ets.lookup(@table, span_data.parent_span_id) | ||
|
|
||
| Enum.each(existing_spans, fn {parent_id, span} -> | ||
| if span.span_id != span_data.span_id do | ||
| :ets.insert(@child_spans_table, {parent_id, span}) | ||
| if span.span_id == span_data.span_id do | ||
| :ets.delete_object(@table, {parent_id, span}) | ||
| :ets.insert(@table, {span_data.parent_span_id, span_data}) | ||
| end | ||
| end) | ||
|
|
||
| :ets.insert(@child_spans_table, {span_data.parent_span_id, span_data}) | ||
| end | ||
|
|
||
| :ok | ||
| end | ||
|
|
||
| def remove_span(span_id) do | ||
| :ets.delete(@root_spans_table, span_id) | ||
| :ets.delete(@table, {:root_span, span_id}) | ||
| :ok | ||
| end | ||
|
|
||
| def remove_child_spans(parent_span_id) do | ||
| :ets.delete(@child_spans_table, parent_span_id) | ||
| :ets.delete(@table, parent_span_id) | ||
| :ok | ||
| end | ||
|
|
||
| # need to ad in sweep for any leftover spans. Should we initiate a sweep on_end or add a ttl or both? | ||
| end | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scope this to Sentry, as the ETS namespace is global. My suggestion is
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In one of our pairing sessions for
check_in_id_mappings.ex, we discussed this being bad practice to have both the GenServer and the table name the same. Thoughts?