elixir如何使用自己的worker
遇到的问题 我自己是先做了足够的解决 无奈没有搞定。
比较详细也比较啰嗦
使用如下命令初始化的工程
mix new hello --sup
我的想法是向通过gen_server定时去更新微信的access_token。
worker如下
defmodule Hello.CentralWorker do use GenServer require Logger @wechat_timeout 1000 #微信更新是两个小时 # api def start_link() do # 以当前模块来命名GenServer :gen_server.start_link(__MODULE__, %{"access_token" => "初始化的access_token", "pid" => 0}, [name: __MODULE__]) end def fetch() do Logger.debug "fetch 获取access_token" :gen_server.call(__MODULE__, :fetch) end # GenServer def init(%{"access_token" => access_token}) do :timer.send_interval @wechat_timeout, :update # timer Logger.debug "gen_server init" {:ok, %{"access_token" => access_token}, 2} end def init(_state) do :timer.send_interval @wechat_timeout, :update Logger.debug "gen_server init" {:ok, %{"access_token" => "" }, 2} end def handle_call(:fetch, _from, %{"access_token" => access_token}) do # 返回当前的access_token GenServer不作状态更新 Logger.debug "handle_call state" {:reply, access_token, %{"access_token" => access_token}} end def handle_call(_data, _from, %{"access_token" => access_token}) do # 返回当前的access_token GenServer不作状态更新 Logger.debug "handle_call state" {:reply, access_token, %{"access_token" => access_token}} end def handle_info(:timeout, state) do Logger.debug "handle_info timeout" {:noreply, state} end def handle_info(:update, _state) do # 更新微信服务器的access_token access_token = "更新微信服务器的access_token" {:noreply, %{"access_token" => access_token} } end end
worker(Hello.CentralWorker, [])
defmodule Hello do use Application # See http://elixir-lang.org/docs/stable/elixir/Application.html # for more information on OTP Applications def start(_type, _args) do import Supervisor.Spec, warn: false children = [ # Define workers and child supervisors to be supervised # worker(Hello.Worker, [arg1, arg2, arg3]), worker(Hello.CentralWorker, []) ] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html # for other strategies and supported options opts = [strategy: :one_for_one, name: Hello.Supervisor] Supervisor.start_link(children, opts) end end
单独使用worker是没有问题的,我知道问题出在 :gen_server.start_link 函数要指定进程的标志,但是mix模式下似乎让__MODULE__失效了,google没有找到对应的东西
各位大神 帮忙看看呗 多谢了。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
引用来自“高田坡”的评论
在Elixir当中应当使用GenServer这个module,非必要的情况下不要使用:gen_server来直接调用Erlang版本的gen_server。__MODULE__这个宏,只要是编译了就会自动被替换掉,和是否适用mix没有关系。核心的问题是erlang版本的:gen_server并不支持name:这个命名参数,如果想使用:gen_server,应当使用start_link/4。写法如下,
:gen_server.start_link(__MODULE__,__MODULE__, %{"access_token"=>"初始化的access_token","pid"=>0}, [])
elixir的GenServer文档 http://elixir-lang.org/docs/stable/elixir/GenServer.html
引用来自“高田坡”的评论
在Elixir当中应当使用GenServer这个module,非必要的情况下不要使用:gen_server来直接调用Erlang版本的gen_server。__MODULE__这个宏,只要是编译了就会自动被替换掉,和是否适用mix没有关系。核心的问题是erlang版本的:gen_server并不支持name:这个命名参数,如果想使用:gen_server,应当使用start_link/4。写法如下,
:gen_server.start_link(__MODULE__,__MODULE__, %{"access_token"=>"初始化的access_token","pid"=>0}, [])
这是
http://erlang.org/doc/man/gen_server.html#start_link-3 erlang关于start_link的文档 还是不是很明白
在Elixir当中应当使用GenServer这个module,非必要的情况下不要使用:gen_server来直接调用Erlang版本的gen_server。__MODULE__这个宏,只要是编译了就会自动被替换掉,和是否适用mix没有关系。核心的问题是erlang版本的:gen_server并不支持name:这个命名参数,如果想使用:gen_server,应当使用start_link/4。写法如下,
:gen_server.start_link(__MODULE__,__MODULE__, %{"access_token"=>"初始化的access_token","pid"=>0}, [])