我正在学习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中正确实现热代码加载?
答案 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