問題タブ [gen-server]
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:gen_serverまたは私自身のカスタムサーバー?
他のモジュールからの指示を受け取り、受け取った指示に応じてアクションを実行するサーバーを作成する必要があります。効率が私の主な関心事です。だから私は自分のサーバーを使うgen_server
のか、それとも自分のサーバーを書くのか。「自分のサーバー」とは、次のような意味です。
したがって、を使用するmyserver
には、プロセスの開始時に登録済みの名前でプロセスを登録し、各クライアントがこのpidを使用してサーバーにメッセージを送信します。
したがって、このメソッドを使用する必要がありますか、それとも代わりにgen_server
動作を使用してサーバーを実装する必要がありますか?使用することに何か利点はありますgen_server
か?しかし、使用gen_server
すると、比較するとオーバーヘッドが追加されmyserver
ますか?
erlang - dictvsmnesiaテーブルvsetsを持つgen_server
erlangサーバーを構築しています。ユーザーはhttpリクエストをサーバーに送信して、ステータスを更新します。サーバー上のhttp要求プロセスは、ユーザーステータスメッセージをメモリに保存します。サーバーは毎分、すべてのメッセージをリモートサーバーに送信し、メモリをクリアします。ユーザーが1分間に数回ステータスを更新すると、最後のメッセージが前のメッセージを上書きします。すべてのメッセージを読み取ってからクリアするまでの間、他のプロセスがステータスメッセージを書き込めないことが重要です。
それを実装するための最良の方法は何ですか?
dictを持つgen_server。キーはユーザーIDになります。dict:store / 3は、ステータスを更新または作成します。gen_serverは、「トランザクション」の問題を解決します。
ram_copiesを含むmnesiaテーブル。トランザクションを処理し、gen_serverを実装する必要はありません。このソリューションにはオーバーヘッドが多すぎますか?
より軽量でgen_serverを持つETSテーブル。ETSで取引を行うことは可能ですか?すべてのメッセージを読んでからクリアするまでの間にテーブルをロックするには?
ありがとう
erlang - erlanggen_serverアプリケーションの起動時にbad_applicationエラーが発生しました
gen_serverを使用して簡単なerlangアプリを作成しました。
application:start(myapp)で起動すると、次のタプルが表示されます...
{エラー、{bad_application、{appliction、myapp ...(残りのアプリケーション構成)。
その他のエラーまたは警告メッセージはありません。また、gen_serverの構成方法とエラー自体の例をグーグルで検索しようとしました。そこに情報がほとんどないことに驚いています。
OTPのデバッグを開始できますか?任意のポインタをいただければ幸いです。
erlang - erlangOTPスーパーバイザーがクラッシュする
私はErlangのドキュメントを調べて、OTPgen_serverとスーパーバイザーのセットアップの基本を理解しようとしています。gen_serverがクラッシュするたびに、スーパーバイザーもクラッシュします。実際、コマンドラインでエラーが発生すると、スーパーバイザーがクラッシュします。
クラッシュしたときにgen_serverが再起動されることを期待しています。コマンドラインエラーは、サーバーコンポーネントにはまったく関係がないと思います。私の上司はまったく墜落してはいけません。
私が使用しているコードは、送信したものすべてに応答する基本的な「エコーサーバー」と、1分間に最大5回(one_for_one)echo_serverを再起動するスーパーバイザーです。私のコード:
echo_server.erl
echo_sup.erl
を使用してコンパイルされerlc *.erl
、次のサンプルが実行されます。
erlang - ダウンしたホストへの接続を再開するための Erlang Supervisor 戦略
私はサービス間のブリッジとして erlang を使用していますが、ダウンした接続を処理するために人々がどのようなアドバイスをしたのか疑問に思っていました。
ローカル ファイルから入力を取得して AMQP にパイプしますが、AMQP ブローカーがダウンする可能性があります。その場合、AMQP サーバーへの接続を再試行し続けたいと思いますが、それらの接続試行で CPU を固定したくありません。私の傾向は、AMQP コードの再起動をスリープ状態にすることです。その「ハック」は本質的に、すぐに失敗して erlang に処理させるという目的を回避するのではないでしょうか? より一般的には、ダウンした接続の処理に erlang スーパーバイザーの動作を使用する必要がありますか?
multithreading - 一時的な gen_server プロセスと pid の更新
私は現在、Erlang をそれなりのペースで学んでいますが、スーパーバイザと一緒に gen_server について質問があります。gen_server プロセスがクラッシュし、結果としてスーパーバイザーによって再起動された場合、プロセスは新しい pid を受け取ります。では、他のプロセスがそのプロセスを Pid で参照したい場合はどうすればよいでしょうか? これらのプロセスでPidを「更新」するための良い慣用的な方法は何ですか?
いくつかの実用的なアプリケーションの演習として、クライアントが任意のキーでロックを要求できるロック サーバーを作成しています。理想的には、特定のロックのロックと解放を別々のプロセスに処理させたいと考えています。これは、gen_server でタイムアウト引数を使用して、N 時間後に誰もプロセスを要求しなかった場合にプロセスを終了できるという考えです。関連するロックはメモリに残ります。これで、ロック名をロック プロセスにマップするディレクトリ プロセスが作成されました。ロック プロセスが終了すると、ディレクトリからロックが削除されます。
私の懸念は、ロック プロセスの終了中にクライアントがロックを要求した場合の処理方法です。まだシャットダウンしていないため、pid が生きていることをスニッフィングしても機能しません。ロック プロセスは、ディレクトリから削除する句にまだ達していません。
これを処理するより良い方法はありますか?
編集
現在、2 つの gen_servers があります。LockName -> Lock Process から ETS テーブルを維持する「ディレクトリ」と、start_child を使用して監視ツリーに動的に追加される「ロック サーバー」です。理想的には、各ロックサーバーがクライアントとの対話を直接処理することを望んでいますが、プロセスがクラッシュしているときに呼び出しまたはキャストで取得/解放の要求が発行されるシナリオについて心配しています (したがって、応答しません)メッセージに)。
{local} または {global} で始まるのは、N 個の数が存在する可能性があるため機能しません。
erlang - デバッグ用に gen_server/gen_fsm の状態を取得する
プロセスの現在の状態を取得することは可能gen_server
ですか (おそらくシステム メッセージを送信することによって)? デバッグ時に役立つ場合があります。
もちろん、現在の状態をhandle_call
次のように返すメッセージを追加できます。
しかし、何かが組み込まれていますか(少しハッキーであっても)?
erlang - gen_server状態にetsテーブルを使用する
etsテーブルを状態として保持したいgen_serverを作成していますが、etsテーブルは別の場所に作成されています。これをgen_serverの状態に追加するにはどうすればよいですか?
メモリを節約したいので、新しいディクショナリを作成するのではなく、etsテーブルを使用したいと思います。
また、etsテーブルをどのように反復しますか?テーブル内の各値を反復または読み取り、値を確認してから、値に応じて2つのオプションのいずれかを実行します。
etsテーブルをリストに変えてリストをトラバースするだけの方が簡単でしょうか?
ありがとう
erlang - Erlang: erlang クラスター内のシングルトン gen_server の最良の方法は?
設定:
erlang クラスターで一意のグローバル登録 gen_server プロセスを開始したいと考えています。プロセスが停止した場合、またはプロセスを実行しているノードがダウンした場合、プロセスは他のノードのいずれかで開始されます。
プロセスはスーパーバイザーの一部です。問題は、gen_server がすでに実行されており、最初のノードからグローバルに登録されているため、2 番目のノードでスーパーバイザーを起動できないことです。
質問:
-
プロセスが gen_server の start_link 関数内で既にグローバルに登録されているかどうかを確認しても問題ありませんか? この場合
{ok, Pid}
、新しい gen_server インスタンスを起動する代わりに、既に実行中のプロセスを返しますか? - このようにして、1 つのプロセスが複数のスーパーバイザーの一部になり、1 つのプロセスがダウンした場合、他のすべてのノードのすべてのスーパーバイザーがプロセスを再起動しようとするのは正しいですか。最初のスーパーバイザーは新しい gen_server プロセスを作成し、他のスーパーバイザーはすべてその 1 つのプロセスに再度リンクします。
global:trans()
gen_server の start_link 関数内である種のものを使用する必要がありますか?
コード例:
erlang - スーパーバイザーの子が start_link からエラーを返したときに、エラーの理由を常にログに記録/表示するにはどうすればよいですか?
gen_server
スーパーバイザー (それ自体はアプリケーションによって開始されます) から を開始する場合、gen_server の が返されない場合に問題が発生start_link
します{ok, ...}
が{error, Reason}
、表示される唯一のエラー メッセージは次のとおりです。
終了するためのReason
ものは表示/ログに記録されません。
これらのエラーがスーパーバイザーに返されるのを確認/記録する方法はありますか?
私が使用している子仕様は、例えば次のとおりです。
編集:明確化
私は error_logger について知っており、すでに使用しています。問題は、何かをログに記録する方法ではなく、スーパーバイザーに終了の理由をログに記録させる方法です。たとえば、誰がエラーを返し、何が返されたかをログに記録します。
そして、これも邪魔にならないようにするために、はい、私は sasl をオンにして erlang を開始します: