Skip to content
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

set_status: use update_element since select_replace doesn't use index #384

Merged
merged 1 commit into from
Apr 27, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 17 additions & 15 deletions apps/opentelemetry/src/otel_span_ets.erl
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,23 @@ add_events(#span_ctx{span_id=SpanId}, NewEvents) ->

-spec set_status(opentelemetry:span_ctx(), opentelemetry:status()) -> boolean().
set_status(#span_ctx{span_id=SpanId}, Status=#status{code=NewCode}) ->
MS = ets:fun2ms(fun(Span=#span{span_id=Id,
status=#status{code=?OTEL_STATUS_ERROR}}) when Id =:= SpanId ,
NewCode =:= ?OTEL_STATUS_OK ->
%% can only set status to OK if it has been set to ERROR before
Span#span{status=#status{code=?OTEL_STATUS_OK}};
(Span=#span{span_id=Id,
status=#status{code=?OTEL_STATUS_UNSET}}) when Id =:= SpanId ->
%% if UNSET then the status can be updated to OK or ERROR
Span#span{status=Status};
(Span=#span{span_id=Id,
status=undefined}) when Id =:= SpanId ->
%% if undefined then the status can be updated to anything
Span#span{status=Status}
end),
ets:select_replace(?SPAN_TAB, MS) =:= 1;
try ets:lookup_element(?SPAN_TAB, SpanId, #span.status) of
#status{code=?OTEL_STATUS_ERROR} when NewCode =:= ?OTEL_STATUS_OK ->
%% can only set status to OK if it has been set to ERROR before
ets:update_element(?SPAN_TAB, SpanId, {#span.status, Status});
#status{code=?OTEL_STATUS_UNSET} ->
%% if UNSET then the status can be updated to OK or ERROR
ets:update_element(?SPAN_TAB, SpanId, {#span.status, Status});
undefined ->
%% if undefined then the status can be updated to anything
ets:update_element(?SPAN_TAB, SpanId, {#span.status, Status});
_ ->
%% nothing to do since status code is either
%% OK or ERROR but NewCode is not OK
false
catch error:badarg ->
false
end;
set_status(_, _) ->
false.

Expand Down
5 changes: 5 additions & 0 deletions apps/opentelemetry/test/opentelemetry_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,11 @@ update_span_data(Config) ->
message = <<>>}, UnsetStatus),
?assertEqual(UnsetStatus, opentelemetry:status(?OTEL_STATUS_UNSET)),

%% successfully set to unset status, replacing `undefined'
?assert(otel_span:set_status(SpanCtx1, UnsetStatus)),
%% successfully set to an error status
?assert(otel_span:set_status(SpanCtx1, ErrorStatus)),
%% successfully set to OK after it was an error already
?assert(otel_span:set_status(SpanCtx1, OkStatus)),
%% spec does not allow setting status to error/unset after it is ok
?assertNot(otel_span:set_status(SpanCtx1, ErrorStatus)),
Expand Down