2017-04-14 9 views
0

私はCowboyとSyncでErlang.mkを使用してアプリケーションを構築しています。再コンパイルはfragments_app(フラグメントは私のプロジェクトの名前です)を除き、ほとんどのモジュールでうまく動作します。私はそこに、ルーティングの構成を有していると私はそれを変更する場合(例えば、新しいルートを追加)私は再コンパイルされたモジュールについての通知を取得しています:アプリケーションモジュールをリロードすると、erlang.mkベースのアプリケーションで有効になりません

=INFO REPORT==== 14-Apr-2017::19:56:59 === 
/app/src/fragments_app.erl:0: Recompiled. 

=INFO REPORT==== 14-Apr-2017::19:56:59 === 
fragments_app: Reloaded! (Beam changed.) 

が、変更が適用されていないようです:

$ http :8080/fragments 
HTTP/1.1 404 Not Found 
content-length: 0 
date: Fri, 14 Apr 2017 19:35:27 GMT 
server: Cowboy 

またコンソール

c:l(fragments_app). 

でモジュールをリロードすると、どちらも

を実行していない、助けません

アプリケーションを停止してもう一度起動すると、正常に動作します。

同時にハンドラを更新するとすぐに効果が発揮されるように見えます - 同期はそれを取り上げて、アプリケーションを再起動せずに効果が発生します。ここで

は、変更後の fragments_app.erlの源である:

-module(fragments_app). 
-behaviour(application). 

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

start(_Type, _Args) -> 
    Dispatch = cowboy_router:compile([ 
    { '_', [ 
     { "/fragments", fragments_http_handler, [] } 
    ]} 
    ]), 
    { ok, _ } = cowboy:start_clear(fragments_http_listener, 100, 
    [{ port, 8080 }], 
    #{ env => #{ dispatch => Dispatch }} 
), 
    fragments_sup:start_link(). 

stop(_State) -> 
    ok. 

私のMakefile:

PROJECT = fragments 
PROJECT_DESCRIPTION = New project 
PROJECT_VERSION = 0.1.0 

DEPS = cowboy sync 
dep_cowboy_commit = master 

DEP_PLUGINS = cowboy 

SP = 2 

include erlang.mk 

とrelx.config:

{release, {fragments_release, "1"}, [fragments, sasl, runtime_tools]}. 
{extended_start_script, true}. 
{sys_config, "rel/sys.config"}. 
{vm_args, "rel/vm.args"}. 
{dev_mode, true}. 

ですが、なぜでしょうか?アプリを再起動せずに変更を適用するためにできることは何ですか?

+0

一部(継続中)の議論は、ここを参照してくださいシーケンスを呼び出す必要があるので、あなたは、それが実行され、それを呼び出して、確認する必要があります/ lhoguin/status/852986294896664576 –

答えて

0

Erlang VMでは、任意のモジュールコードの2つのバージョンをロードすることができます。

次に、各プロセスは、完全修飾呼び出しを使用してモジュール関数の1つを呼び出すまで、現在のバージョンを実行し続けます:module:function(Par ...)。この場合、新しいコードバージョンが使用されます。 code_changeコールバックを提供するOTPビヘイビアを使用すると便利です。

これは、各プロセスが変更を適用するタイミングを「決定」できるようにし、バージョン変更(たとえばデータの順応)を管理する関数を呼び出すことができるためです。

モジュールfragments_appには、アプリケーションの動作があります。このアプリケーションは、アプリケーションを起動して停止するためにのみ呼び出されます。 https://twitter.com:あなたはすべての変更を適用したい場合は、

application:stop(fragments_app), 
application:start(fragments_app), 
... 
+0

ありがとう@Pascal。これらは確かに貴重な洞察です。残念ながら、あなたが提供したコードは私のためには機能しません。Erlangには私の特定の問題にあなたの一般的な発言を適用するのに十分な経験はありません。私は '{error、{not_started、fragments_app}}'を得る。私はそれが 'relx'がどのように動作するかに特有だと思います。 –

+0

取得したメッセージは、アプリケーションfragments_appがまだ開始されていないことを意味します。それが正常かどうかは言えません。私はrelxには慣れていませんが、relx.configはフラグメントのみを参照しているので、 "application:stop(fragments)"と "application:start(fragments)" – Pascal

関連する問題