I wrote a simple application in Erlang, but it refuses to work with the following error:
=SUPERVISOR REPORT==== 18-Jan-2012::15:03:27 ===
Supervisor: {<0.60.0>,my_sup}
Context: start_error
Reason: {'EXIT',{undef,[{my,start,[{8077,none}]},
{supervisor,do_start_child,2},
{supervisor,start_children,3},
{supervisor,init_children,2},
{gen_server,init_it,6},
{proc_lib,init_p_do_apply,3}]}}
Offender: [{pid,undefined},
{name,my},
{mfa,{my,start,[{8077,none}]}},
{restart_type,permanent},
{shutdown,brutal_kill},
{child_type,worker}]
=INFO REPORT==== 18-Jan-2012::15:03:27 ===
application: my
exited: {shutdown,{my_app,start,[normal,[noarg]]}}
type: temporary {error,{shutdown,{my_app,start,[normal,[noarg]]}}}
And the modules:
my.erl
-module(my).
-export([start/2, stop/0]).
start(Port,_arg) ->
io:format("starting my").
stop() ->
ok.
my_app.erl Application module, perform application behavior.
-module(my_app).
-behaviour(application).
-export([start/2, stop/1]).
start(_Type, _Args) ->
io:format("my server starting~n"),
my_sup:start_link().
stop(_State) ->
io:format("my server terminating~n"),
ok.
my_sup.erl Supervisor logic
-module(my_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
start_link() ->
supervisor:start_link(my_sup, []).
init(_Args) ->
{ok, {
{one_for_one, 10, 60},
[{my, {my, start, [{8077,none}]
},
permanent, brutal_kill, worker, [my]}]}}.
Config file (my.app):
{application, my,
[
{description, "Demo"},
{vsn, "1.0"},
{id, "hello"},
{modules, [my,my_sup]},
{registered, [my,my_sup]},
{applications, [kernel, stdlib]},
%%
%% mod: Specify the module name to start the application, plus args
%%
{mod, {my_app, [noarg]}},
{env, []}
]
}.
I changed child spec like you recommend, but the problem still remains.
=SUPERVISOR REPORT==== 19-Jan-2012::00:34:21 ===
Supervisor: {<0.96.0>,my_sup}
Context: start_error
Reason: <0.97.0>
Offender: [{pid,undefined},
{name,my},
{mfa,{my,start,[8077,none]}},
{restart_type,permanent},
{shutdown,brutal_kill},
{child_type,worker}]
=ERROR REPORT==== 19-Jan-2012::00:34:21 ===
Error in process <0.97.0> with exit value:
{{badmatch,{error,eaddrinuse}},[{my,'- start/2-fun-0-',1}]}
=INFO REPORT==== 19-Jan-2012::00:34:21 ===
application: my
exited: {shutdown,{my_app,start,[normal,[noarg]]}}
type: temporary
{error,{shutdown,{my_app,start,[normal,[noarg]]}}}
The my:start/2 should take two arguments but in the child specification you only give it one argument ({8077,none}). You could change the child spec to:
{my, {my, start, [8077,none]}, permanent, brutal_kill, worker, [my]}
As an aside your indentation and line breaking of the Supervisor Specification is a bit off making it difficult to see what belongs to what.
EDIT: Comment to new error
This is not the same problem as before. You are getting a new error, eaddrinuse, which normally means you are trying to use an IP address/port which is already in use. This would imply you are doing some socket programming in your code.
Your supervisor specifies that my:start should take one argument, but it takes two. You probably want to change the child spec to:
{one_for_one, 10, 60},[{my, {my, start, [8077,none]}
Your my:start/2 provides a wrong return value.
Supervisor expects tuple {ok,Pid}, while your function simply returns ok (the last call is to io:format, which returns ok, so your function also does).
If you want to use a supervisor, you must spawn a new process and link it to the supervisor. For example
start(_) -> {ok,spawn_link(fun() -> io:format("~w started~n",[self()]),timer:sleep(5000),io:format("~w exiting~n",[self()]) end)}.
should do the job for you.
Related
I am stuck in a bit of a fix trying to run gen_server on another node. So I have a common gen_server class which looks like this
start(FileName) ->
start_link(node(), FileName).
start_link(ThisNode, FileName) ->
gen_server:start_link({local, ?MODULE}, ?MODULE, [ThisNode, FileName], []).
init([ThisNode, FileName]) ->
process_flag(trap_exit, true),
{ok, Terms} = file:consult(FileName),
{A1, B1, C1} = lists:nth(1,Terms),
place_objects(A1, B1, C1).
Now I want to start multiple nodes that will run the same gen_server and somehow communicate with each other, and use a another node to orchestrate that. (All these nodes are started on my local terminal).
So I start a new node in one terminal using erl -sname bar where I intend to run the gen_server, and compile the gen_server module on this node. Then I start another node called 'sup' which I intend to use as a coordinator for all the other nodes. If I run the command my_gen_server:start("config_bar.txt"). on bar, it successfully returns but when I run the command rpc:call('bar#My-MacBook-Pro', my_gen_server, start, ["config_bar.txt"]). on sup, it successfully returns from the init method (I checked this by putting in the logs) but immediately after that, I get this error:
{ok,<9098.166.0>}
(sup#My-MacBook-Pro)2> =ERROR REPORT==== 21-Feb-2022::11:12:30.443051 ===
** Generic server my_gen_server terminating
** Last message in was {'EXIT',<9098.165.0>,
{#Ref<0.3564861827.2990800899.137513>,return,
{ok,<9098.166.0>}}}
** When Server state == {10,10,#Ref<9098.1313723616.3973185546.82660>,
'bar#My-MacBook-Pro'}
** Reason for termination ==
** {#Ref<0.3564861827.2990800899.137513>,return,{ok,<9098.166.0>}}
=CRASH REPORT==== 21-Feb-2022::11:12:30.443074 ===
crasher:
initial call: my_gen_server:init/1
pid: <9098.166.0>
registered_name: my_gen_server
exception exit: {#Ref<0.3564861827.2990800899.137513>,return,
{ok,<9098.166.0>}}
in function gen_server:decode_msg/9 (gen_server.erl, line 481)
ancestors: [<9098.165.0>]
message_queue_len: 0
messages: []
links: []
dictionary: []
trap_exit: true
status: running
heap_size: 1598
stack_size: 29
reductions: 3483
neighbours:
I can't seem to figure out what causes the error and if there's anything I need to add to my gen_server code to fix it. Would really appreciate some help on this one!
The gen_server in the remote node is linked to an ephemeral process created for the rpc call.
As this ephemeral process exits with a term that's different from normal (the actual result of the rpc call), the exit signal propagates to the gen_server, killing it.
You can use gen_server:start instead of gen_server:start_link or, if you want the gen_server to be part of the supervission tree, instruct its supervisor to spawn it:
rpc:call('bar#My-MacBook-Pro', my_gen_sup, start_child, ["config_bar.txt"]).
I'm trying to create two instances of webmachine in one erlang application. Each instance is to run on a different port and has its own specific configuration. Following the webmachine doc here, I have added the following processes to be started in my supervisor spec (application_sup.erl):
{
webmachine_instance_1,
{ webmachine_mochiweb, start,
[
[
{ ip, "0.0.0.0"},
{ port, 8000},
{ dispatch, [ {["*"], file_resource, []} ] }
]
]
},
permanent,
5000,
worker,
dynamic
},
{
webmachine_instance_2,
{ webmachine_mochiweb, start,
[
[
{ ip, "0.0.0.0"},
{ port, 8080},
{ dispatch, [ {["*"], file_resource, []} ] }
]
]
},
permanent,
5000,
worker,
dynamic
}
When I include both instances, I get a start error and cannot start my erlang application. After just trying to run the application with a single instance of webmachine (webmachine_instance_1 OR webmachine_instance_2), my application starts up fine.
Here is the specific error:
=PROGRESS REPORT==== 11-Mar-2014::17:00:31 ===
supervisor: {local, application_sup}
started: [{pid,<0.230.0>},
{name,webmachine_instance_1},
{mfargs,
{webmachine_mochiweb,start,
[[{ip,"0.0.0.0"},
{port,8000},
{dispatch, [{['*'],
file_resource,
[]
}]}]
]
}
},
{restart_type,permanent},
{shutdown,5000},
{child_type,worker}]
=SUPERVISOR REPORT==== 11-Mar-2014::17:00:31 ===
Supervisor: {local, application_sup}
Context: start_error
Reason: {'EXIT',
{undef,
[{webmachine_mochiweb,start,
[{ip,"0.0.0.0"},
{port,8080},
{dispatch,[{["*"],file_resource,[]}]}],
[]},
{supervisor,do_start_child,2,
[{file,"supervisor.erl"},{line,303}]},
{supervisor,start_children,3,
[{file,"supervisor.erl"},{line,287}]},
{supervisor,init_children,2,
[{file,"supervisor.erl"},{line,253}]},
{gen_server,init_it,6,
[{file,"gen_server.erl"},{line,304}]},
{proc_lib,init_p_do_apply,3,
[{file,"proc_lib.erl"},{line,227}]}]}}
Offender: [{pid,undefined},
{name,webmachine_instance_2},
{mfargs,
{webmachine_mochiweb,start,
[{ip,"0.0.0.0"},
{port,8080},
{dispatch,[{["*"],file_resource,[]}]}]}},
{restart_type,permanent},
{shutdown,5000},
{child_type,worker}]
I am fairly new to erlang and might not quite understand the underlying issues here - according to the webmachine doc we should be able to start two instances of the same application but with different configurations in an erlang app.
Thanks for any help/discussion on this issue!
Your child process config should have the following form:
{Name,
{webmachine_mochiweb, start, [WebConfig]},
permanent, 5000, worker, [mochiweb_socket_server]}
where Name and WebConfig must be unique to your webmachine instance. The WebConfig part should include name and dispatch_group properties. For example:
WebConfig = [{name,instance1},
{dispatch_group,instance1},
{ip, Ip},
{port, Port},
{log_dir, "priv/log"},
{dispatch, Dispatch}],
So, for multiple instances you might have something like this for your supervisor spec:
WebConfig1 = [{name,instance1},
{dispatch_group,instance1},
{ip, Ip},
{port, Port},
{log_dir, "priv/log"},
{dispatch, Dispatch}],
WebConfig2 = [{name,instance2},
{dispatch_group,instance2},
{ip, Ip},
{port, Port+1},
{log_dir, "priv/log"},
{dispatch, Dispatch}],
Web1 = {instance1,
{webmachine_mochiweb, start, [WebConfig1]},
permanent, 5000, worker, [mochiweb_socket_server]},
Web2 = {instance2,
{webmachine_mochiweb, start, [WebConfig2]},
permanent, 5000, worker, [mochiweb_socket_server]},
Processes = [Web1, Web2],
{ok, { {one_for_one, 10, 10}, Processes} }.
One other thing: judging from the name application_sup appearing in your question, you may have run the webmachine ./scripts/new_webmachine.sh and specified the application name as application. If so, don't do this, since application is the name of a key Erlang OTP module, and your code will clash with it and cause all kinds of problems.
I am having trouble starting the cowboy application it is giving me following error. For some reason the ranch is not starting, although I have added code to start the ranch in my application.
I see a new git repo cowlib being pulled. but still having trouble.
1> application:start(satomi).
{error,
{bad_return,
{{satomi_app,start,[normal,[]]},
{'EXIT',
{noproc,
{gen_server,call,
[ranch_sup,
{start_child,
{{ranch_listener_sup,http},
{ranch_listener_sup,start_link,
[http,100,ranch_tcp,
[{port,9090}],
cowboy_protocol,
[{...}]]},
permanent,5000,supervisor,
[ranch_listener_sup]}},
infinity]}}}}}}
=INFO REPORT==== 12-Sep-2013::11:42:46 ===
application: satomi
exited: {bad_return,
{{satomi_app,start,[normal,[]]},
{'EXIT',
{noproc,
{gen_server,call,
[ranch_sup,
{start_child,
{{ranch_listener_sup,http},
{ranch_listener_sup,start_link,
[http,100,ranch_tcp,
[{port,9090}],
cowboy_protocol,
[{env,
[{dispatch,
[{'_',[],[{[],[],toppage_handler,[]}]}]}]}]]},
permanent,5000,supervisor,
[ranch_listener_sup]}},
infinity]}}}}}
type: temporary
Following is my app.src
>cat satomi.app.src
{application, satomi,
[
{description, ""},
{vsn, "1"},
{registered, []},
{applications, [
kernel,
stdlib,
cowboy
]},
{mod, { satomi_app, []}},
{env, []}
]}.
>cat satomi.erl
-module(satomi).
-export([start/0]).
start()->
ok = application:start(crypto),
ok = application:start(sasl),
ok = application:start(ranch),
ok = application:start(cowlib),
ok = application:start(cowboy),
ok = application:start(satomi).
I am trying to figure out what's going wrong here
Can anyone point me to the working sample of cowboy that I can use as a template. I am using rebar to compile the code. I don't think that should make any difference.
I am using following command to start the application
erl -pa ./ebin ./deps/*/ebin
When calling application:start(satomi) from the shell it doesn't automatically start the applications it depends on, those need to be started manually.
The satomi:start/0 function you have does exactly this, so the solution is to call satomi:start() from the shell.
The reason is that application:start(satomi) will actually not call satomi:start(), it is a convenience method for starting the application and its dependencies when the application is not part of an Erlang release.
UPDATE: Since Erlang R16B02, there is also application:ensure_all_started. It starts all the dependencies automatically.
I try to write application to my Erlang program.
I have test_app.erl:
-module(test_app).
-behaviour(application).
%% Application callbacks
-export([start/2, stop/1]).
start(_Type, _StartArgs) ->
test_sup:start_link().
stop(_State) ->
ok.
And .app file:
{application, test,
[{description, "test system."},
{vsn, "1.0"},
{modules, [test_app, test_sup, fsm]},
{registered, [test_sup, fsm]},
{applications, [kernel, stdlib]},
{mod, {test_app, []}}
]}.
When i try to start application:
application:start(test).
I get error:
=INFO REPORT==== 18-Feb-2011::19:38:53 ===
application: test
exited: {bad_return,
{{test_app,start,[normal,[]]},
{'EXIT',
{undef,
[{test_sup,start_link,[[]]},
{test_app,start,2},
{application_master,start_it_old,4}]}}}}
type: temporary
{error,{bad_return,{{test_app,start,[normal,[]]},
{'EXIT',{undef,[{test_sup,start_link,[[]]},
{test_app,start,2},
{application_master,start_it_old,4}]}}}}}
What's wrong? How can i fix it?
If i make in eshell:
test_app:start(normal, []).
Than all works.
Thank you.
I suppose this might be caused by not loading the [proper] .beam. Ensure that all modules are in the same directory, or try to use -pa key to erl(1), e. g.:
$ erl -pa ../ebin
1> application:start(test).
...
I try to spawn new process and register it:
-module(db).
-export([start/0]).
start() ->
register( db , spawn( db, abs, [-100])).
But when i try in erlang shell:
1> db:start().
I see:
true
(emacs#myhost)2>
=ERROR REPORT==== 1-Dec-2010::17:42:27 ===
Error in process <0.112.0> on node 'emacs#myhost' with exit value: {undef,[{db,abs,[-100]}]}
What's wrong?
Thank you.
This fails because db:abs/1 is not defined.