私は潜在的に高いレートでポイントを生成するデータソースを持っており、各ポイントで時間のかかる操作を実行したいと思います。私はまた、過剰なデータポイントを落とすことによってシステムが過負荷になったときに、システムが正常に機能しなくなることを望みます。erlang/OTPのレート制限付きイベントハンドラ
私が知る限り、gen_eventを使用するとイベントはスキップされません。概念的には、私がgen_eventをしたいのは、ハンドラを再度実行する前に、最新の保留中のイベント以外のすべてを破棄することです。
標準のOTPでこれを行う方法はありますか?そういうことをしてはならない理由があるのでしょうか?
これまでのところ、私は高価なイベントトリガするgen_serverを使用して、タイムアウトに依存して持っている最高:
-behaviour(gen_server).
init() ->
{ok, Pid} = gen_event:start_link(),
{ok, {Pid, none}}.
handle_call({add, H, A},_From,{Pid,Data}) ->
{reply, gen_event:add_handler(Pid,H,A), {Pid,Data}}.
handle_cast(Data,{Pid,_OldData}) ->
{noreply, {Pid,Data,0}}. % set timeout to 0
handle_info(timeout, {Pid,Data}) ->
gen_event:sync_notify(Pid,Data),
{noreply, {Pid,Data}}.
は、このアプローチは正しいですか? (特に監督に関して)
"データを待っているワーカープロセスのキュー"は、Erlangのようには聞こえません。 Erlangの利点の1つは、新しいプロセスを生成するのが安価であり、完了した作業でそれらを終了させることです。あなたは過負荷状態を避けるために、gen_server内の稼働中のワーカーの数を数えることができます。あるいは、さらに簡単に:プロセスがまだ周りにいる場合、プロセスを自分自身で撃つことができます。しかし、複数のワーカー・プロセスは、SMPマシンでのみ役に立ちます。 –
優れた点。私は最近脳に「データを待っているプロセス」を持っていましたが、ここでそれらを使う必要は全くありません。残りの答えはどう思いますか? – ellisbben
私はすべてを完全に理解していないかもしれませんが、これは別の問題を解決すると思います。固定のDiscardAfter間隔にコミットしたくありません。たぶん別の言い方をすると、古いデータを処理する時間を無駄にせずに、自分の処理の結果が常に私が知っている最新のデータポイントを反映してほしいということです。しかし、必要な処理量は動的に変化する可能性があり、ソースのデータレートも変化する可能性があります。 – b0fh