我有一个包含许多模块的项目,每个模块都有不同的运行线程。我写了一个小脚本,遍历每个脚本并安全地重新加载代码(用于热交换):
reload_all() ->
?MODULE:reload_all(?MODULE_LIST).
reload_all([]) -> ok;
reload_all([T|C]) ->
io:fwrite("Purging ~w\n",[T]),
try_purge(T),
{module,T} = code:load_file(T),
?MODULE:reload_all(C).
try_purge(T) -> try_purge(T,1).
try_purge(T,Wait) ->
case code:soft_purge(T) of
true -> ok;
false ->
io:fwrite("* Waiting ~w seconds for ~w module\n",[Wait,T]),
timer:sleep(Wait*1000),
try_purge(T,Wait+1)
end.
它使用soft_purge()函数,该函数仅在没有线程运行将被普通purge命令杀死的“旧”代码时清除代码。它将等待增加间隔并继续尝试。我设计了这个项目,以便等待的时间永远不会超过一分钟,但实际上它应该总是或多或少是即时的。
我遇到的问题是,有时一个模块会有一个错误导致它因某种原因无限期地阻塞,而我的reload_all()脚本永远不会完成。这是理想的行为,它让我知道出了什么问题。问题是,追踪错误涉及大量的测试和分析代码,有时甚至不起作用,因为错误只出现在生产环境而不是测试中。
我的问题是:有没有办法确定哪些线程在模块中运行“旧”代码,并查看它们当前卡在哪个函数中?
答案 0 :(得分:1)
您可以使用erlang检查您是使用旧版本还是新版本:check_old_code / 1和erlang:check_process_code / 2。只需看Erlang manual。