Erlang的FSM code_change函数用法

时间:2015-12-10 18:12:04

标签: erlang

我正在学习Erlang并且我已经学习了热代码加载,但我不知道gen_fst行为的code_change函数是如何工作的。我也找不到它的任何例子。

我应该像这样创建一个动作:

public class PrefixedNumericStringComparer : IComparer<string>
{
    public string Prefix { get; private set; }

    public PrefixedNumericStringComparer(string prefix)
    {
        if (prefix == null)
            throw new ArgumentNullException();
        this.Prefix = prefix;
    }

    #region IComparer<string> Members

    int? GetNumber(string value)
    {
        if (value == null)
            return null;
        if (value.StartsWith(Prefix))
        {
            var s = value.Substring(Prefix.Length);
            int iValue;
            if (int.TryParse(s, NumberStyles.None, NumberFormatInfo.InvariantInfo, out iValue))
                return iValue;
            return null;
        }
        return null;
    }

    public int Compare(string x, string y)
    {
        var iX = GetNumber(x);
        var iY = GetNumber(y);
        if (iX == null && iY == null)
            return string.Compare(x, y, StringComparison.Ordinal);
        else if (iX == null)
            return 1;
        else if (iY == null)
            return -1;
        else return iX.Value.CompareTo(iY.Value);
    }

    #endregion
}

在各州都有一个处理程序:

upgrade() ->
    gen_fsm:send_event(machine_name, upgrade).

我试过了,但some_state(upgrade, State) -> code:purge(?MODULE), compile:file(?MODULE), code:load_file(?MODULE), {next_state, some_state, State, 1000}. 函数没有执行。我应该如何在我的FSM中正确实现热代码加载?

1 个答案:

答案 0 :(得分:2)

code_change函数调用由主管在执行relup时编排。正常的热代码加载是此需要的低级功能。

如果您只想更换一个模块而不需要升级您的状态,您通常只需从外壳加载新模块(无需清除,实际上可能有害)。

每个模块最多有两个版本在运行。在进行本地呼叫时(在呼叫中没有模块名称),您将保留旧版本。但是,当您进行合格的调用(带模块名称)时,您将始终跳转到新代码。

loop(S) ->
   do_processing(S),   % stays in the same version
   ?MODULE:loop(S).    % always jumps to the newest version

对于更复杂的热门升级,您需要appups和relups这是一个高级主题,最佳介绍是in LYSE