elixir如何使用自己的worker

发布于 2021-11-29 11:06:00 字数 3063 浏览 792 评论 5

遇到的问题 我自己是先做了足够的解决 无奈没有搞定。

比较详细也比较啰嗦

使用如下命令初始化的工程

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 主要是这一行

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

别再吹冷风 2021-12-03 22:42:08

引用来自“高田坡”的评论

在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}, [])

私藏温柔 2021-12-03 22:23:38

elixir的GenServer文档 http://elixir-lang.org/docs/stable/elixir/GenServer.html

疾风者 2021-12-03 21:48:18

引用来自“高田坡”的评论

在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}, [])

噩梦成真你也成魔 2021-12-03 13:21:53

这是 
http://erlang.org/doc/man/gen_server.html#start_link-3  erlang关于start_link的文档 还是不是很明白

月亮是我掰弯的 2021-11-30 20:15:31

在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}, [])

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文