2017-04-14 9 views
0

저는 Erlang.mk를 사용하여 카우보이 및 동기화 응용 프로그램을 구축하고 있습니다. 재 컴파일은 fragments_app을 제외하고 대부분의 모듈에서 잘 작동합니다 (fragments는 프로젝트의 이름입니다). 나는 거기 라우팅 구성을 가지고 있고 나는 그것을 변경하는 경우 (예를 들어, 새 경로를 추가) 내가 다시 컴파일 된 모듈에 대한 통지를 받고 있어요 :응용 프로그램 모듈을 다시로드하면 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. 

내 메이크 :

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

일부 진행중인 토론은 다음을 참조하십시오. https://twitter.com/lhoguin/status/852986294896664576 –

답변

0

Erlang VM에서는 모듈 코드의 두 가지 버전을로드 할 수 있습니다.

그런 다음 각 프로세스는 정규화 된 호출 module : function (Par ...)을 사용하여 모듈 함수 중 하나를 호출 할 때까지 현재 버전을 계속 실행합니다. 이 경우 새 코드 버전을 사용합니다. code_change 콜백을 제공하는 OTP 비헤이비어를 사용하는 것이 유용한 이유는입니다.

이 이유는 변경을 적용 할 때 각 프로세스가 "결정할"수 있으며 버전 변경 (예 : 데이터 적응)을 관리하는 함수를 호출 할 수도 있기 때문입니다.

모듈 fragments_app에는 응용 프로그램 동작이 있으며 응용 프로그램의 별표를 표시하고 중지하기 위해서만 호출됩니다. 변경 사항을 적용하려면 해당 코드를 호출하여 실행해야하므로 시퀀스를 호출해야합니다.

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