2

現在、Erlang アプリケーションは escript (TCP サーバー) 内で開始され、提供されたデフォルトのポートを使用するため、すべて正常に動作します。今、escriptを介してポートをアプリケーションに渡したいのですが、方法がわかりません。(アプリはスーパーバイザーを実行します)

script.escript

!/usr/bin/env escript
%% -*- erlang -*-

-export([main/1]).

main([UDPort, TCPort]) ->
   U = list_to_integer(UDPort),
   T = list_to_integer(TCPort),

    app:start(), %% Want to pass T into the startup.
  receive
    _ -> ok
  end;

...

app.erl

-module(app).
-behaviour(application).

-export([start/0, start/2, stop/0, stop/1]).

-define(PORT, 4300).

start () -> application:start(?MODULE). %% This is called by the escript.
stop () -> application:stop(?MODULE).

start (_StartType, _StartArgs) -> supervisor:start(?PORT).
stop (_State) -> ok.

アプリケーションを使用してこれが可能かどうかは正直わかりませんが、尋ねるのが最善だと思いました.

4

1 に答える 1

2

一般的な方法は、呼び出したばかりのシェルから開始することです

erl -run foo

しかし、あなたもできる

erl -appname key value

環境値を設定してから

application:get_env(appname, key)

探している値を取得します。

それは言った...

私は、サービス アプリケーションを (再) 構成するためにシャットダウンする必要がないものにしたいと考えています。{config, Aspect, Setting}私は通常、サービスの基本的な状態をオンザフライで変更できるようなメッセージ プロトコルを含めます。私はよくこれを行うので、通常は、アプリケーションを起動するスクリプトに構成メッセージを送信させることになります。

したがって、これを念頭に置いて、次の大まかな概念例を検討してください。

!/usr/bin/env escript
%% -*- erlang -*-

-export([main/1]).

main([UDPort, TCPort]) ->
    U = list_to_integer(UDPort),
    T = list_to_integer(TCPort),
    ok = case whereis(app) of
        undefined ->  app:start();
        _Pid      ->  ok
    end,
    ok = set_ports(U, T).

%% Just an illustration.
%% Making this a synchronous gen_server/gen_fsm call is way better.
set_ports(U, T) ->
    app ! {config, listen, {tcp, T}},
    app ! {config, listen, {udp, U}},
    ok.

現在、起動スクリプトは起動スクリプトであるだけでなく、構成スクリプトでもあります。重要なのは、起動スクリプトを用意することではなく、指定したポートでサービスを実行することです。もちろん、これはすべてのツールに概念的に適合するわけではありませんが、いくつかのアイデアが得られるはずです。また、アプリケーションが認識している場所に構成ファイルを配置し、そこから用語を読み取るだけの手法もあります (アプリケーション仕様にポートを含めるなど)。

編集

呼び出すたびに新しいノードを生成する escript でこれを行っていることに気付きました。上記の手法を適切に機能させるには、escript 名をサービスを実行するためのノードにし、既に存在する場合はその場所を特定する必要があります。

于 2015-04-07T11:49:56.523 に答える