我定义了一个像这样的宏:
defmodule Test do
defmacro __using__ do
quote do
require Test
import Test
end
end
defmacro my_macro do
quote do
Gernserver.call() # generic server call from other module
end
end
end
我在我正在构建的lib中包含此代码。在另一个应用程序中测试此lib时,我会在具有use Test
。
错误:exited in: GenServer.call ...
exit no process
(在my_macro调用的行上,更具体地说是在genserver调用上)。好像genserver没有运行,并不是因为它是编译时间。
将一个简单的Application.ensure_all_started(:lib_name)添加到使用宏似乎可以解决问题。但话说回来,在编译时代码不应该运行,我是对的吗?或者这里是我没有看到的东西?也许我不能在宏上使用genserver调用?
感谢。
答案 0 :(得分:1)
您在编译阶段TestScheduler
中正在调用every
。
应该将所有计划初始化代码放在一个函数中,在运行阶段中显式调用,或者简单地
引入一个新的GenServer
,将其添加到受监管的列表中(以使Elixir在应用启动时自动运行它),并在其every
中执行此start_link
初始化(或任何其他功能明确地稍后调用):
defmodule Test.Scheduler do
use GenServer
use Cronex.Scheduler
def start_link ... do
every :minute do
IO.puts "every minute job"
end
every :minute do
IO.puts "every minute job 2"
end
end
end
另一种方式(如果你想让文件保持尽可能干净),将收集every
宏中的数据,而将产生所有调用在运行阶段。
要更熟悉阶段,请将以下代码放入/tmp/test.ex
:
defmodule A do
IO.puts "Here “every” macro was called: compilation"
def a do
IO.puts "Is not called during compilation stage"
end
end
IO.puts "=== compilation finished ==="
A.a
问题elixir /tmp/test.ex
:
Here “every” macro was called: compilation
=== compilation finished ===
Is not called during compilation stage