scoutapp / scout_apm_elixir

ScoutAPM Elixir Agent. Supports Phoenix and other frameworks.
https://scoutapm.com
Other
36 stars 20 forks source link

compile error when channel controller contains more than one @transaction/2 #35

Closed jonathanleang closed 7 years ago

jonathanleang commented 7 years ago

when I have 2 @transaction in my channel controller, I got compile error.... one is fine, anything more is error.

@transaction(type: "web", name: "RoomChannel.message:all")
def handle_in("message:all", message, socket) do
...
end

@transaction(type: "web", name: "RoomChannel.message:others")
def handle_in("message:others", message, socket) do
...
end
== Compilation error on file web/channels/room_channel.ex ==
** (ArgumentError) cannot make function handle_in/3 overridable because it was not defined
    (elixir) lib/module.ex:804: anonymous fn/2 in Module.make_overridable/2
    (stdlib) lists.erl:1338: :lists.foreach/2
    lib/scout_apm/tracing/annotations.ex:79: anonymous fn/2 in ScoutApm.Tracing.Annotations.instrument_transactions/1
    (elixir) lib/enum.ex:1229: Enum."-map/2-lists^map/1-0-"/2
    (elixir) lib/enum.ex:1229: Enum."-map/2-lists^map/1-0-"/2
    expanding macro: ScoutApm.Tracing.Annotations.before_compile/1
    web/channels/room_channel.ex:1: Darkmoor.RoomChannel (module)
    (elixir) lib/kernel/parallel_compiler.ex:117: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1

also tried without @transaction, still doesn't work.

def handle_in("message:all", message, socket) do
    transaction(:web, "Do Work") do
      broadcast! socket, "message:new", %{
        user: socket.assigns.user,
        body: message,
        timestamp: :os.system_time(:milli_seconds)
      }
      {:noreply, socket}
    end
end

have derek have reproduced this bug from slack help

cschneid commented 7 years ago

This is a dupe of #34.

The first half is fixed in #36, and will be released soon in the next version of the agent.

The second half is related to how Elixir names macros when included via use. It doesn't attempt to import them into your environment.

So you have 2 options in that case:

Use the complete module name:

use ScoutApm.Tracing

def interesting() do
  ScoutApm.Tracing.transaction(:background, "Work") do
    # ...
  end
end

Import it to avoid retyping the namespace:

use ScoutApm.Tracing
import ScoutApm.Tracing

def interesting() do
  transaction(:background, "Work") do
    # ...
  end
end

Technically, you can even get away without the use call in the second example. That's only required if you're using the @transaction module-attribute approach to tracing. But leaving it also doesn't hurt.

cschneid commented 7 years ago

Released in agent version 0.3.2