0

2 つのモードで実行できるアプリを構築しています。サンドボックス モードと本番モード。

サンドボックス モードでは、gen_server でデータベースに対して多くのチェックを行いたいと考えています。テーブルが存在しない場合は作成します。列が存在しない場合は追加します。列のタイプで保存したい値が許可されていない場合は、変更します。

本番モードでは、テーブルが存在しない場合、または列が値の型と一致しない場合は失敗しますが、それで問題ありません。

したがって、「case State#state.is_sandbox of true -> ...」のような面倒なコードを避けるために、gen_server に 2 つの異なるモジュールを用意し、現在のモジュールを handle_call またはハンドル情報。

本当は、サンドボックスから本番環境に移行したいだけなのですが、この方法でうまくいけば逆にうまくいくのではないかと思います。

ありがとう。

4

4 に答える 4

3

moduleモジュールの名前である を gen_server の状態に追加できます。次に、同じ機能を実装するサンドボックスとプロダクションの 2 つのモジュールが必要になります (そのための動作を作成できます)。

gen_server コールバックが呼び出さmodule:functionれます。これは、サンドボックスまたは運用モジュールからの関数になります。これは、gen_server の関数でmodule設定できますinit。変更するには、新しい関数を gen_server に追加するだけです。

use_production() ->
    gen_server:cast(production).

....

handle_cast(production, State) ->
    {noreply, State#state{module = production}).

サンドボックス モジュールについても同様です。

を使用した gen_server のコールバックの例module:

handle_call(Msg, _From, #state{module = Module} = State) ->
    Module:function(Msq),
    {reply, ok, State}.

function、サンドボックス モジュールと本番モジュールの両方に実装する必要があります。

于 2013-02-06T21:12:41.710 に答える
1

を使用してモジュール名を取得できますos:getenv/1(もちろん、その前に異なる環境で異なる名前を設定する必要があります)

于 2013-02-06T18:42:18.353 に答える
1

の代わりに、このケースを非常に簡単に処理できる有限状態マシンを使用できgen_serverます。状態に応じて異なるモジュールで関数を呼び出す複数の状態があります。明示的なパラメーターを運ぶ必要なく、基本的にすべての処理を行います。基本的にFSMを手作業で実装しています。gen_fsmstate

于 2013-02-07T20:52:24.157 に答える
1

gen_event代わりに単一のハンドラーで a を使用できます。これにより、swap_handlerタプルを返すことができます ( gen_event/handle_*を参照) 。

また、gen_server モデルで case ステートメントを使用する必要はありません。状態にサンドボックス変数が含まれている場合、ヘッダーでサンドボックス値をバインドすることにより、コールバック関数にさまざまな句を定義できます。例えば:

handle_call(do_stuff, _From, State = #state{sandbox = true}) ->
    do_sandbox_stuff();
handle_call(do_stuff, _From, State) ->
    do_nonsandbox_stuff().

このセットアップでは、erlang は、別のハンドラーを定義したり、case ステートメントを使用したりすることなく、サンドボックス変数の値に基づいて起動する正しい句を自動的に選択します。このように関数句で変数をバインドすることも、効率を高めるための良い方法です (変数は関数の本体の外でバインドされるため、バインド プロセスはスケジューラで行われ、その結果、関数の実行時間に対してカウントされません。一方、すべてのマッチングはケース内の関数本体内で行われます)

于 2013-02-06T19:11:15.797 に答える