1

私はたくさんのモジュールを持っているプロジェクトを持っています、それぞれが異なる実行中のスレッドを持っています。それぞれを調べてコードを安全にリロードする小さなスクリプトを作成しました(ホットスワップ用):

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()スクリプトが完了しない場合があることです。これは望ましい動作であり、何かが間違っていることを知らせてくれます。問題は、バグを追跡するためにコードのテストと分析が大量に行われることです。バグは本番環境にのみ表示され、テスト環境には表示されないため、機能しない場合もあります。

私の質問は、モジュール内で「古い」コードを実行しているスレッドを特定し、それらが現在スタックしている関数を確認する方法はありますか?

4

1 に答える 1

1

erlang:check_old_code / 1とerlang:check_process_code / 2を使用して、モジュールの古いバージョンと新しいバージョンのどちらを使用しているかを確認できます。Erlangのマニュアルをご覧ください。

于 2012-05-08T08:17:03.387 に答える