即使在连续的热代码升级中将vsn固定为最新版本时,GenServer的code_change也再次被调用?

时间:2018-09-17 07:04:24

标签: elixir

第二个升级版本无法成功安装。从下面的错误日志中,似乎再次调用了code_change函数并错误地处理了状态。

复制步骤

我正在遵循“ Programming Elixir> = 1.6”一书第20章OTP.Applications中的示例和步骤。

  • 在提交one时,我已将应用程序准备为0.2.0版本
  • 在提交two时,server.ex中的状态已更新,需要运行code_change。我可以成功将代码热升级到0.3.0。

经过上述两个步骤,如果我只是在next_number的{​​{1}}函数中更改返回文本,并将版本升级到0.3.1,例如,保持步骤2中的code_change函数不变,升级将失败,并出现以下错误。

在第2步之后,我确实多次运行了新功能server.exSequence.Server.next_number(),以确保其生效并将状态更新为新格式。

问题是,为什么在第二次升级中仍可以触发标记为最新版本的Sequence.Server.increment_number(2)

错误日志

  

发布处理程序无法安装:{:code_change_failed,

     

PID <10063.770.0>,Sequence.Server,“ 1”,{:EXIT,{:function_clause,[{Sequence.Server,:code_change,[“ 1”,%{ struct

     

Sequence.Server.State,当前编号:8,增量:2},[]],[文件:   'lib / sequence / server.ex',行:44]},{:gen_server,   :system_code_change,4,[file:'gen_server.erl',line:794]},{:sys,   :do_change_code,5,[file:'sys.erl',line:573]},{:sys,:do_cmd,6,   [file:'sys.erl',line:465]},{:sys,:handle_system_msg,8,[file:   'sys.erl',行:365]},{:proc_lib,:init_p_do_apply,3,[文件:   'proc_lib.erl',行:249]}]}}}

问题描述

预期结果是什么?热代码升级应该成功
什么版本的酿酒厂? 2.0.9
您在哪个操作系统的Erlang / Elixir版本上看到此问题? Mac 10.13.6,Elixir 1.7.2

这个问题实际上也是在Github中作为issue酿酒厂提出的。

1 个答案:

答案 0 :(得分:1)

该调用失败,因为它尝试使用code_change作为第一个参数来调用您的"1"函数-阅读错误消息。它从提交的参数开始。您当前的代码仅允许您(BEAM等)以“ 0”作为第一个参数来调用code_change/3函数。其他情况不匹配/不允许。

如果要为code_change函数添加另一个匹配子句,则可以忽略/处理"1"的版本更改:

def code_change("0", old_state = current_number, _extra) do
  new_state = %State{
    current_number: current_number,
    delta: 1
  }
  IO.puts inspect old_state
  IO.puts inspect new_state
  { :ok, new_state }
end
def code_change("1", state, _extra) do
  # your code here for version "1"
  {:ok, state}
end
def code_change(_version, state, _extra) do
  # your code here for any other version
  {:ok, state}
end