問題タブ [erlang-otp]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
erlang - Erlang/OTPフレームワークのerror_loggerはかなり高い負荷でハングします
私のアプリケーションは基本的に、MMSイベントをルーティングするコンテンツベースのルーターです。
私が使用しているロガーは、SASLモードのOTPフレームワークに付属しているロガー「error_logger」です。
問題は::
クライアントを使用して、デフォルト値でMMSイベントを生成しています。このクライアント(Java)には、複数のスレッドで大量のイベントを送信する機能があります
Erlang / OTPで書かれたルーターに10スレッドで100イベントを送信しています(各スレッドは10 MMSイベントを送信しています)。
問題は、ルーターがこのような高負荷を受信すると、ロガーがハングする、つまりログファイルの更新を停止することです。ただし、ルーターは引き続きイベントをルーティングできます。
私が思いついた結論は::
このような高負荷のイベントを受信した場合のErlangでのスケジューリングの問題(イベントごとに個別のプロセス)。
非常にありそうもないデッドロック状態。
イベントを順番に送信するのではなく、複数のスレッドでイベントを送信することが原因である可能性があります。しかし、ルーターは複数のサービスプロバイダーボックスに接続されると思うので、スレッドでイベントを送信することを考えました。
誰かが問題を解明するのにmwを助けることができますか?
events - Erlang/OTPでgen_eventハンドラーを切り替えながらイベントが処理されるようにする
ハンドラーのバージョンがいくつかgen_event
あり、プログラムの実行中にそれらを変更したいとします。
明らかに、1つのハンドラーを削除し、もう1つのハンドラーを追加することで、それらを切り替えることができます。
しかし、これは競合状態の可能性を残します。間違ったタイミングでイベントを受信した場合error_man
、そのイベントはログに記録されません。または、アクションの順序を変更すると、2回ログに記録されますが、これも望ましくありません。一度正確に処理されたことを確認するにはどうすればよいですか?
この場合、ハンドラーを1つだけ持つことができ、ログレベルをとして維持できますState
が、これは受け入れられないとします。
erlang - バックオフのある監督者
リモートサーバーへの接続を処理するTCPクライアントと接続プロトコルを処理するFSMの2つのワーカープロセスを持つスーパーバイザーがいます。
子プロセスでTCPエラーを処理すると、コードが大幅に複雑になります。したがって、「クラッシュさせる」ことをお勧めしますが、これには別の問題があります。サーバーに到達できない場合、再起動の最大数にすぐに到達し、スーパーバイザーがアプリケーション全体とともにクラッシュします。これは、この場合。
私が望んでいるのは、バックオフを使用した再起動戦略を立てることです。これに失敗した場合は、クラッシュが原因で再起動されたときにスーパーバイザーが認識していれば十分です(つまり、init
関数にパラメーターとして渡された場合)。このメーリングリストのスレッドを見つけましたが、より公式でよりテストされたソリューションはありますか?
erlang - 受信したメッセージを gen_fsm 状態のコールバックで処理できますか?
gen_fsm プロセスの pid に送信されたメッセージは、状態コールバックでイベントとして一致することに気付きました。これは単なる偶然ですか、それともこの機能に頼ることができますか?
通常、gen_fsm に送信された一般的なメッセージが handle_info/3 コールバックに表示されることを期待し、gen_fsm:send_event を使用して再送信する必要があると考えていました。
gen_fsm はメッセージを最初に状態コールバックに一致させ、次に常に handle_info/3 コールバックに一致させようとしますか? それとも、状態コールバック句に一致しない場合のみですか?
ただし、試してみると、デバッグ出力によると、メッセージが2回処理されているようです。
したがって、基本的には、次のように質問することもできます: 受信したメッセージを gen_fsm 状態関数のイベントとして正しく処理する方法は?
明確化:メッセージが渡されることによってイベントの一部が発生していることは、この質問に与えられていると見なす必要があります。
多くの場合、fsm への関数呼び出しのみを使用してプロトコルを可視化する方がクリーンであることは承知しています。
これが、前述の gen_fsm が適合しなければならない現在のフレームワークを改善するかどうかはよくわかりません。各層が connect() 関数を呼び出して下位層をアタッチする (場合によっては開始する) 多様なプロトコル スタック。パケットは、関数を呼び出すことで下位層に送信され (send) receive
、メッセージを送信することで受信されます。gen_tcp によく似ています。
gen_fsm のコードを見ると、一般的なメッセージは handle_info にのみ渡されることがわかったので、問題は、handle_info/3 コールバックから状態関数を直接呼び出すか、gen_fsm:send_event を使用して再送信するかだけです。
erlang - 柔軟な Erlang プロトコル スタック作成 API の設計方法
現在のアプローチに満足できず、Erlang でプロトコル スタックを構築する方法を再設計しようとしています。重要度順に並べられた機能:
パフォーマンス
新しいプロトコルバリアントを追加する柔軟性と実装速度
開発者がシェルからプロトコルのバリアントを探索するのに役立ちます
私の現在のモデル(すでにこの質問で説明されています)は、関数呼び出しによる send() とメッセージによる受信の醜い非対称性に加えて、限界に達しています。
プロトコル エンジン全体の全体像は次のようになります。
下部:
各スタックの下部にいくつかのポートまたは場合によっては gen_tcp もあります (独立したチャネル用に複数の同一のスタックがあるため、ここでプロセスを登録するだけで静的になりすぎることはできず、どこにでも PID を渡す必要があります。
ポートの上には、スーパーバイザーによって管理されるいくつかのモジュールがあります (システムで開始され、エラーが発生しない限り、存続期間全体が維持されます)。
頭の部分:
(event_handler の意味ではなく一般的な意味で) イベントの発生によってトリガーされるのは、接続指向のプロトコルの終わりです (たとえば、
connect()
およびclose()
セマンティクスを使用)。スタックを形成するために互いの上に積み重ねられたモジュールは動的に構成可能であり、接続ごとに変更される可能性があるため、プロトコルスタックのトップエンドはおそらく動的にのみ開始できます。
現在計画されているのは、モジュール名のリスト + オプションのパラメーターをトップレベルから渡すことであり
connect()
、スタックに呼び出されている間に消費されます。トップレベルのプロセスがリンクされるため、ここで何か問題が発生すると、接続全体が失敗します。
モジュールの種類とモジュール間の通信の種類
これまでに見つかったいくつかの種類のモジュールがあります。
ステートレス フィルター モジュール
状態を持つモジュールは、一部は gen_server に適合し、一部は gen_fsm に適合しますが、ほとんどは単純なサーバー ループになるでしょう。
レイヤー間の通信の種類:
独立したパケットの送受信(外から見て独立)
何かを送信し、応答があるまでブロックし、結果を戻り値として返す同期呼び出し。
複数のモジュールと通信するマルチプレクサ (議論を容易にするためにここで定義しています)
上向きのモジュールと通信するための異なるアタッチメント ポイント (現在はアトムによって名前が付けられています) を持つデマルチプレクサ。
現在、私の唯一のデマルチプレクサはスタックの静的な下部にあり、動的に作成された上部にはありません。マルチプレクサは現在、上部のみにあります。
リンクされた以前の質問処理の回答とコメントで、一般的に API はメッセージではなく関数のみで構成されるべきであると聞きましたが、そうでないと確信しない限り、これに同意します。
問題の説明が長くなってしまい申し訳ありませんが、あらゆる種類のプロトコルの実装にまだ一般的に使用されていると思います。
ここで一般的に役立つ何かを達成するために、これまでに計画したことを回答に書き、結果として得られる実装とそれに関する私の経験についても説明します。
erlang - Erlang/OTP で application:get_env() を使用するには?
mochiweb インスタンスを作成しました
myserver_web.erl
アプリケーション構成にアクセスできます
ただし、room.erl
では、アプリケーション構成 (特にenv
リスト) にアクセスできません。
スーパーバイザーは部屋を開始しませんし、私もそれを望んでいません。
私は OTP に不慣れで、おそらく何かばかげたことをしていることに気づきましたが、誰かの助けに本当に感謝しています。
乾杯!
erlang - OTPプロセスのスーパーバイザーを見つける方法は?
OTPプロセスがスーパーバイザーのpidを見つけることを可能にする機能はありますか?
erlang - Java から Erlang へのメッセージ
Java の GUI を使用して、Erlang でアプリケーションを作成しています。言語間の接続を確立することができましたが、ボタンを押すたびに Java から Erlang にメッセージを送信する必要があります (おそらく)。
それは正しい方法ですか?
そのようなメッセージはどのように見えますか?
この形式の統合に関するいくつかの優れたサイトを見つけましたが、すべてが得られていないように感じます.
erlang - gen_fsmの初期状態、スポーン時にイベントを送信
イベントを生成したときに常にイベントをgen_fsmの初期状態に送信したい場合、その関数呼び出しをどこに置く必要がありますか?start_linkの直後、または最初にstart_linkを呼び出したプロセスから。ここにベストプラクティスはありますか?
erlang - ワーカープロセスが停止したときのデータの永続性、どのように?
起動時に引数として収集/計算されたデータを必要とするワーカープロセスがあります。これは、再起動時にも必要になります。初期化コードはどこに置くべきですか?スーパーバイザーの初期化の内部?またはモジュールの内部start_link、またはinit?これに関して、Erlangにベストプラクティスはありますか?