キーに関連付けられている一時的な gen_servers 状態の保存を処理する方法を知りたいです。
キーをプロセスに関連付けるために、pidstore というプロセスを使用します。Pidstore は最終的にプロセスを開始します。Key と M、F、A を pidstore に渡すと、グローバルでキーが検索され、見つかった場合は pid が返されるか、MFA が適用され ({ok, Pid} が返される必要があります)、Pid がキーに登録されます。グローバルで、Pid を返します。
おそらく巨大な状態の非アクティブな gen_servers が多数ある可能性があります。したがって、handle_info コールバックを設定して状態をデータベースに保存し、プロセスを停止しました。gen_servers はスーパーバイザーでは一時的なものと見なされるため、何かが再び必要になるまで再起動されません。
ここで問題が発生します: {car, 23} を表すプロセスで handle_info を保存するステップで、{car, 23} などのキーを使用してプロセスを呼び出すと、意図したとおりに pid が返されます。プロセスは保存中で、終了していません。したがって、gen_server:call でプロセスを呼び出しますが、プロセスが停止しているため、応答がありません (デフォルトの 5 秒のタイムアウトに達します)。(問題A)
この問題を解決するには、プロセスをグローバルから登録解除し、その状態を保存してから停止します。ただし、登録解除後、保存が完了する前に必要な場合は、新しいプロセスをロードします。このプロセスは、更新されていない値をデータベースにロードする可能性があります。(問題B)
これを再度解決するために、データベースへの読み込みと保存がキューに入れられ、同時に実行できないようにすることができました。これがボトルネックになる可能性があります。(問題C)
私は別の解決策を考えています.私のプロセスは、保存する前に、ビジーであることをpidstoreに伝えることができます. pidstore は、使用中のプロセスのリストを保持し、これらのキーに対するすべての要求に対して「使用中」と応答します。保存が完了すると、pidstore はプロセスによって no_more_busy と通知され、キーを要求されたときに新しいプロセスを開始できます。(古いプロセスが終了していなくても、保存が完了しているため、一人で死ぬのに時間がかかる場合があります)。
これは少し面倒に思えますが、可能性のあるタイムアウトを処理するために gen_server へのすべての呼び出しをラップする代わりに、キーから Pid を取得するためにいくつかの試行を行う方が簡単に感じます。(プロセスが終了しているが、まだグローバルに登録されている場合)。
これらの半分の問題と半分の解決策のすべてについて、私は少し混乱しています。この状況で使用する設計は何ですか、またはこの状況を回避するにはどうすればよいですか?
私のメッセージが判読できることを願っています。英語のエラーについても教えてください。
ありがとうございました