【问题标题】:Elixir: defmacro and benchmark of piplineElixir:管道的defmacro和基准
【发布时间】:2021-03-08 00:59:07
【问题描述】:

我有宏可以帮助我测量延迟:

  defmacro instrument_duration(endpoint_name, block) do
    quote do
      {time, value} = :timer.tc(fn -> unquote(block) end)
      Histogram.observe(
        [name: :endpoint_duration_seconds, labels: [endpoint_name]],
        time
      )
      value
    end
  end

以下代码正在使用它:

    response =
      Instrumenter.instrument_duration(id,
        do_handle(params, context)
        |> prepare_response())

但我收到Reason:undef\n', options: [] 错误。我在这里做错了什么?这是正确的方法吗?

【问题讨论】:

  • labels: [endpoint_name]labels: [unquote(endpoint_name)],因为在编译过程中你应该被警告告知。如果你想拥有一个健壮的代码,编译器警告是不容忽视的。另外,很高兴看到整个错误消息,请下次发布。
  • 谢谢你,阿列克谢!顺便说一句,我的错误信息很差,就像这样:[msg: 'Unexpected error during request processing. Handler:\'Elixir.App.Module\'; Reason:undef\n', options: []]我可以用那个做点什么吗?我的代码中有什么东西会吞下完整的错误消息吗?
  • 嗯。我不知道“请求”在这里是什么意思以及它是如何处理的,但我会明确隔离测试以仅测试这个特定的宏。喜欢模拟Histogram 并直接测试Instrumenter.instrument_duration/2

标签: macros elixir benchmarking duration


【解决方案1】:

我将这里作为答案。

TL;DR: labels: [endpoint_name]labels: [unquote(endpoint_name)]


您的代码没有在引用块内取消引用 endpoint_name,导致编译器尝试在引用块的上下文中解析 endpoint_name 失败。

幸运的是, 在编译阶段提供了警告,肯定有类似

warning: variable "endpoint_name" is unused (if the variable
         is not meant to be used, prefix it with an underscore)

如果一个人想要有一个健壮的代码,编译器警告是不容忽视的,它们是故意提供的,应该被考虑在内。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 2011-06-10
    • 2021-03-27
    相关资源
    最近更新 更多