私はたくさんのモジュールを持っているプロジェクトを持っています、それぞれが異なる実行中のスレッドを持っています。それぞれを調べてコードを安全にリロードする小さなスクリプトを作成しました(ホットスワップ用):
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()関数を使用します。この関数は、通常のパージコマンドによって強制終了される「古い」コードを実行しているスレッドがない場合にのみコードをパージします。それは増加する間隔で待機し、試行を続けます。私は、待機が合計で1分を超えないようにプロジェクトを設計しましたが、現実的には、常にほぼ瞬時に待機する必要があります。
私が遭遇している問題は、モジュールにバグがあり、何らかの理由でモジュールが無期限にブロックされ、reload_all()スクリプトが完了しない場合があることです。これは望ましい動作であり、何かが間違っていることを知らせてくれます。問題は、バグを追跡するためにコードのテストと分析が大量に行われることです。バグは本番環境にのみ表示され、テスト環境には表示されないため、機能しない場合もあります。
私の質問は、モジュール内で「古い」コードを実行しているスレッドを特定し、それらが現在スタックしている関数を確認する方法はありますか?