gen_fsm タイムアウトについて質問があります。2 つの状態を持つ gen_fsm のセットがあるとしましょう (将来はそれ以上になる可能性があります):idle
これは開始状態とworking
.
gen_fsm は 5 秒ごとに特定のパラメータをチェックし、それに従って に留まるか、idle
または に移動しworking
ます。gen_fsm が に移動するときはいつでも、working
メッセージを ( を使用してgen_fsm:send_all_state_event/2
) 他のすべての gen_fsm にidle
送信working
しworking
ます。
ここで重要なのは、ステート タイムアウトに偏りを持たせたくないということです (たとえば、マシンがworking
3 秒間待機してメッセージを受信するとどうなるでしょうか? 5 秒のタイムアウトは有効ではありません。何があっても一定のタイムアウト (これは、一定の時間にタイムアウト メッセージをトリガーする必要があることを意味します)。
now()
とを使用する私のソリューションの重要な部分は次のとおりtime:now_diff/2
です。とにかく小さなドリフトがありますが、ほんの数秒について話しているので、公平に思えます。
それは有効だと思いますか?
{ok, idle, #state{time = now()}, 5000}.
idle(timeout, State) ->
%% do some operations
{next_state, idle, State#state{time = now()}, 5000}.
working(timeout, State) ->
%% do some other actions
{next_state, working, State#state{time = now()}, 5000}.
handle_event(work, working, #state{time = Time} = State) ->
Timeout = round(timer:now_diff(now(), Time) / 1000),
{next_state, working, State, Timeout}.
handle_event(work, StateName, state{time = Time} = State) ->
Timeout = round(timer:now_diff(now(), Time) / 1000),
{next_state, working, State, Timeout}.