0

何時間も稼働する erlang gen_server プロセスを実装する必要があります。ただし、タイムアウト後に gen_server プロセスを強制終了する必要があります。これらのプロセスは動的に開始されるため、動的監視が使用されます。アイデアは、プロセスの初期化で timer:apply_after() を使用することです。したがって、gen_server プロセスの init は次のようになります。

init(Time) -> 
   timer:apply_after(Time, my_supervisor, kill_child, [self()]),
   % do other init things
   ok.

私はアーランに少し慣れていないので、質問はこのアプローチがうまくいくか、それともいくつかの欠点があるかということです. より良い解決策はありますか?

ありがとう!

4

3 に答える 3

0

このコードを試すことができます:プロセスは毎秒シャットダウンworker1し、プロセスworker2は2秒ごとにシャットダウンします。2 つのビームをロードしてsuper:start_link(). super:main().、erl シェルで実行するだけです。

これはスーパーバイザーです:

-module(super).
-behaviour(supervisor).
%% API
-export([start_link/0]).
-export([stop/0]).
-export([main/]).
%% Supervisor callbacks
-export([init/1]).

-define(SERVER, ?MODULE).

start_link() ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).

init([]) ->
    RestartStrategy = simple_one_for_one,
    MaxRestarts = 1000,
    MaxSecondsBetweenRestarts = 3600,

    SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},

    Restart = permanent,
    Shutdown = 2000,
    Type = worker,

    AChild = {worker, {worker, start_link, []},
          Restart, Shutdown, Type, [worker]},
    {ok, {SupFlags, [AChild]}}.

main() ->
    add_worker(worker1, 1000),
    add_worker(worker2, 2000).

add_worker(WorkerName, Time) when is_atom(WorkerName)->
    supervisor:start_child(?SERVER, [WorkerName, Time]).
stop() ->
    exit(whereis(?SERVER), shutdown).

これは gen_server です:

-module(worker).
-behaviour(gen_server).
%% API
-export([start_link/2]).

%% gen_server callbacks
-export([init/1, handle_call/3, handle_cast/2, handle_info/2,
     terminate/2, code_change/3]).

-define(SERVER, ?MODULE). 

-record(state, {}).

start_link(WorkerName, Time) ->
    io:format("server: ~p start!~n", [WorkerName]),
    gen_server:start_link({local, WorkerName}, ?MODULE, [WorkerName, Time], []).

init([WorkerName, Time]) ->
    erlang:send_after(Time, self(), {WorkerName, timeout_shutdown}),
    {ok, #state{}}.


handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.


handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info({WorkerName, timeout_shutdown}, State) ->
    io:format("server: ~p timeout_shutdown!~n", [WorkerName]),
    {stop, normal, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.
于 2014-04-02T09:19:42.753 に答える