Skip to content

Instantly share code, notes, and snippets.

@garthk
Last active July 8, 2020 23:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save garthk/fb0d89181372136f150d7adc539356c3 to your computer and use it in GitHub Desktop.
Save garthk/fb0d89181372136f150d7adc539356c3 to your computer and use it in GitHub Desktop.

StartSpan

Demonstrates a problem with :opencensus typing.

To reproduce: mix dialyzer.

To reproduce from the gist:

cd `mktemp -d`
git clone https://gist.github.com/garthk/fb0d89181372136f150d7adc539356c3
cd fb0d89181372136f150d7adc539356c3
docker build -t start_span .
docker run --rm -ti start_span

Output after rebuilding PLTs:

lib/start_span.ex:13:no_return
Function fail/0 has no local return.
________________________________________________________________________________
lib/start_span.ex:14:call
The function call will not succeed.

StartSpan.start_span(<<102, 97, 105, 108>>, :undefined, [{:kind, :SERVER}])

will never return since it differs in arguments with
positions 2nd from the success typing arguments:

(
  binary(),
  {:span_ctx, :undefined | non_neg_integer(), :undefined | non_neg_integer(),
   :undefined | integer(), :undefined | {:tracestate, [any()]}},
  Keyword.t()
)
# docker build -t start_span .
# docker run --rm -ti start_span
FROM elixir:1.10.3-alpine
RUN cd /usr/local/src && mix new start_span
WORKDIR /usr/local/src/start_span
COPY mix.exs README.md ./
COPY start_span.ex lib/
RUN mix local.hex --force && mix local.rebar --force && mix deps.get
CMD ["mix", "dialyzer"]
defmodule StartSpan.MixProject do
use Mix.Project
def project do
[
app: :start_span,
version: "0.1.0",
elixir: "~> 1.10",
start_permanent: Mix.env() == :prod,
deps: [
{:dialyxir, "~> 1.0.0", only: [:dev], runtime: false},
{:opencensus, "~> 0.9.3", override: true}
],
dialyzer: [plt_add_deps: [:app_tree]]
]
end
def application, do: [extra_applications: [:logger]]
end
# lib/start_span.ex
defmodule StartSpan do
@moduledoc """
Demonstrates a problem with `:opencensus` typing.
To reproduce: `mix dialyzer`.
"""
@doc """
Call `start_span/3` with an `:undefined` parent.
"""
def fail do
start_span("fail", :undefined, kind: :SERVER)
end
@doc """
Start a new span with `:oc_trace.start_span/3`.
"""
@spec start_span(
name :: binary(),
parent_span_ctx :: :undefined | :opencensus.span_ctx(),
opts :: [
{:attributes, :opencensus.attributes()}
| {:kind, :SERVER | :CLIENT | :SPAN_KIND_UNSPECIFIED}
]
) :: :opencensus.span_ctx()
def start_span(name, parent_span_ctx, opts \\ []) do
{attributeses, opts} = Keyword.pop_values(opts, :attributes)
{kind, opts} = Keyword.pop(opts, :kind, :SPAN_KIND_UNSPECIFIED)
for {k, _} <- opts, do: raise(ArgumentError, "no such option: #{k}")
:oc_trace.start_span(
name,
parent_span_ctx,
%{
kind: kind,
attributes: attributeses |> Enum.flat_map(& &1) |> Enum.into(%{})
}
)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment