变更非Erlang代码

变更用Erlang之外的编程语言所写的程序的代码,比如一个端口程序,是和应用紧密相关的,OTP没有为此提供特别的支持。

例如,更改端口程序的代码:假设控制该port的Erlang进程是一个 gen_server portc 同时该端口是在回调函数 init/1 中打开的:

  1. init(...) ->
  2. ...,
  3. PortPrg = filename:join(code:priv_dir(App), "portc"),
  4. Port = open_port({spawn,PortPrg}, [...]),
  5. ...,
  6. {ok, #state{port=Port, ...}}.

如果要更新端口程序,那么我们可以扩展gen_server的代码,加入一个关闭旧端口并打开新端口。(如果必要的话,gen_server可以先从端口程序请求需要保存的数据,然后将这些数据传送到新的端口中):

  1. code_change(_OldVsn, State, port) ->
  2. State#state.port ! close,
  3. receive
  4. {Port,close} ->
  5. true
  6. end,
  7. PortPrg = filename:join(code:priv_dir(App), "portc"),
  8. Port = open_port({spawn,PortPrg}, [...]),
  9. {ok, #state{port=Port, ...}}.

.app 文件中更新应用版本并编写一个 .appup 文件:

  1. ["2",
  2. [{"1", [{update, portc, {advanced,port}}]}],
  3. [{"1", [{update, portc, {advanced,port}}]}]
  4. ].

确保C程序所在的 priv 目录也被包含在了新的发布包中:

  1. 1> systools:make_tar("my_release", [{dirs,[priv]}]).
  2. ...