1

次のように構成された Elixir アプリケーションがあります。

Application --> Supervisor --> Worker

アプリケーション モジュールは非常に単純でuse Application

def start(_type, _args)
  MyApp.Supervisor.start_link()
end

Supervisor はもう少し複雑です。

def start_link() do
    {:ok, pid} = Supervisor.start_link(__MODULE__, [], name: __MODULE__)
    halt_exit(wait_for_child())
    {:ok, pid}
end

def init(data) do
    children =
    [
        worker(MyApp.Worker, [], restart: :transient)
    ]

    Supervisor.init(children, [strategy: :one_for_one])
end

wherehalt_exit(pid)は aProcess.sleep(100)を実行し、プロセス pid がまだ生きていることがわかるたびに自分自身を呼び出し (または pid がもう生きていない場合は単に nil を返します)、wait_for_childWorker モジュールの pid を見つけます (開始されるまで待たなければならない可能性があることを考慮して) .

私の Worker モジュールは、 と を使用してユーザーと対話しIO.putsますIO.gets。なぜこのような複雑で不必要なロジックが必要なのですか? のようだ

  • mix run を使用し、halting exit を省略すると、アプリケーションがすぐに終了する
  • mix release (distillery) を使用しmyapp.bat consoleて cmd から実行し、停止中の終了を省略すると、アプリケーションが起動し、すぐに終了し、iex が起動します
  • mix release を使用しmyapp.bat console、halting exit を含めると、アプリは正しく出力されますが、入力を受け取ることができません (これは、werl.exe のウィンドウに入力できないことを意味します)。
  • mix release w/ を使用myapp.bat foregroundすると、アプリが起動し、バッチ ファイルにエラーが発生します(システムはファイル `%get_pid_cmd%` を見つけることができません。エラー: 検索フィルターを認識できません。'@call' は認識されません)。内部コマンドまたは外部コマンド、操作可能なプログラムまたはバッチ ファイルとして。) その時点でアプリが終了します。
  • mix run --no-halt (アプリ内に exit-halting ロジックがない) を使用すると、アプリが起動し、すぐに終了し、erlang VM は cmd ウィンドウで実行されたままになります
  • run と include を混在させた場合にのみhalt_exit/1、アプリが期待どおりに動作します

これらすべてから、私は次のように結論付けました。1) アプリケーション モジュールがstart/2戻った瞬間に、アプリはシャットダウンされます。Elixir は、アプリケーションのメイン以外ではなく、他のプロセスに負荷をかけるアプリケーション向けに設計されているため、あまり意味がありません。モジュール。2) 入力はメイン アプリケーション モジュールのプロセスを介して行われます (ただし、何らかの理由で別の werl.exe ウィンドウで実行された場合のみ、mix run で正常に動作するようです)、blocking-until-work-finished を配置できません。ユーザー入力が必要な場合は、そこにロジックがあります。

どうすればこれを解決できますか? 同様に重要なことに (将来の問題を回避できるように)、どのような動作が問題を引き起こしているのでしょうか? mixとErlang VMがインストールされていないコンピューターでこれを実行できる必要があるため、私の唯一のオプションは、生成されたdistilleryパッケージで動作させることですが、現時点ではできません。

いくらグーグルで調べても、人為的に終了を停止するための同様の戦術に私を導いたことはなく、私が見つけたフォーラム/チュートリアルでは、この「早期終了」の問題について言及していないので、これを解決する正しい方法は、どうにかしてそれを望ましくないものにすることだと思いますプロセスの実行中に終了します。

4

1 に答える 1

0

システムはファイルを見つけることができません%get_pid_cmd%。エラー: 検索フィルターを認識できません

次の行で:

@for /f "delims=" %%i in (`%%get_pid_cmd%%`) do set pid=%%i

バッククォート%%get_pid_cmd%%を一重引用符に変更してみてください。

また、次の行で:

set get_pid_cmd=%escript% %nodetool% eval %node_type% %node_name% -setcookie "!cookie!" "erlang:list_to_integer(os:getpid()).'

最後の一重引用符を二重引用符に変更します。

ソース: https://www.bountysource.com/issues/50408118-starting-in-foreground-mode-on-windows-fails-to-get-pid-and-returns-errorlevel-1

boot_win.eex でこれら 2 つの変更を行い、_build フォルダーを削除し、再構築するとうまくいきました。

于 2017-12-05T22:48:02.800 に答える