- 变更内部状态
变更内部状态
在这种情况下,简单代码替换就不够了。进程必须在切换到新版本的回调模块之前,明确地使用回调函数 code_change 转换它的状态。这样就必须使用同步代码替换。
例如:想一下来自 gen_server行为 一章的 gen_server ch3 。内部状态是一个表示可用频道的 Chs 值。假设我们想添加一个计数器 N 用来跟踪目前的 alloc 请求数。这就表示我们需要将格式更改为 {Chs,N} 。
.appup 文件可以为:
- {"2",
- [{"1", [{update, ch3, {advanced, []}}]}],
- [{"1", [{update, ch3, {advanced, []}}]}]
- }.
update 指令的第三个元素是一个元组 {advanced,Extra} ,它说受影响的进程要在载入新版本的模块之前进行一个状态转换。进程会调用回调函数 code_change (参见 gen_server(3) )。 Extra ,在这里是 [], 会原样传递给该函数:
- -module(ch3).
- ...
- -export([code_change/3]).
- ...
- code_change({down, _Vsn}, {Chs, N}, _Extra) ->
- {ok, Chs};
- code_change(_Vsn, Chs, _Extra) ->
- {ok, {Chs, 0}}.
如果是降级,那么第一个参数是 {down,Vsn} ,如果是升级,那么则是 Vsn 。表达式 Vsn 是由模块的“原始”版本中获得的,即,由哪个版本升级来的,或者要降级到哪个版本。
版本由模块属性 vsn 定义——如果有。在 ch3 中没有这种属性,这种情况下则是BEAM文件的校验和(一个大整数),这个值没什么意思所以在这里忽略掉。
( ch3 的其他回调函数也需要进行修改,可能还需要添加新的借口函数,就不在此展示了)。