Erlang sellaprime OTP application - erlang

I'm trying to run the sellaprime example OTP application from Chapter 23 of Programming Erlang 2nd Ed. I have uploaded the code to https://github.com/myles-mcdonnell/sellaprime
After compiling with rebar I run erl from the root, then switch dir ..
1> c(src).
/Users/mylesmcdonnell/sellaprime/src
ok
then I load the app..
2> application:load(sellaprime).
ok
then I try to start the app..
3> application:start(sellaprime).
=CRASH REPORT==== 5-Feb-2015::09:55:34 ===
crasher:
initial call: application_master:init/4
pid: <0.48.0>
registered_name: []
exception exit: {bad_return,
{{sellaprime_app,start,[normal,[]]},
{'EXIT',
{undef,
[{sellaprime_app,start,[normal,[]],[]},
{application_master,start_supervisor,3,
[{file,"application_master.erl"},
{line,326}]},
{application_master,start_the_app,5,
[{file,"application_master.erl"},
{line,308}]},
{application_master,start_it_new,7,
[{file,"application_master.erl"},
{line,294}]}]}}}}
in function application_master:init/4 (application_master.erl, line 133)
ancestors: [<0.47.0>]
messages: [{'EXIT',<0.49.0>,normal}]
links: [<0.47.0>,<0.7.0>]
dictionary: []
trap_exit: true
status: running
heap_size: 610
stack_size: 27
reductions: 124
neighbours:
=INFO REPORT==== 5-Feb-2015::09:55:34 ===
application: sellaprime
exited: {bad_return,
{{sellaprime_app,start,[normal,[]]},
{'EXIT',
{undef,
[{sellaprime_app,start,[normal,[]],[]},
{application_master,start_supervisor,3,
[{file,"application_master.erl"},{line,326}]},
{application_master,start_the_app,5,
[{file,"application_master.erl"},{line,308}]},
{application_master,start_it_new,7,
[{file,"application_master.erl"},
{line,294}]}]}}}}
type: temporary
{error,
{bad_return,
{{sellaprime_app,start,[normal,[]]},
{'EXIT',
{undef,
[{sellaprime_app,start,[normal,[]],[]},
{application_master,start_supervisor,3,
[{file,"application_master.erl"},{line,326}]},
{application_master,start_the_app,5,
[{file,"application_master.erl"},{line,308}]},
{application_master,start_it_new,7,
[{file,"application_master.erl"},{line,294}]}]}}}}}
Clearly something is undefined but I'm struggling to determine what? I have lifted the code directly from the book download site with no changes.

Related

Deploying Elixir Docker to Heroku. Can't set long node name

I'm trying to deploy a Dockerfile to Heroku and when the app starts, it immediately crashes with this error:
=INFO REPORT==== 2-Apr-2022::16:20:30.959748 ===
Can't set long node name!
Please check your configuration
=SUPERVISOR REPORT==== 2-Apr-2022::16:20:30.960208 ===
supervisor: {local,net_sup}
errorContext: start_error
reason: {'EXIT',nodistribution}
offender: [{pid,undefined},
{id,net_kernel},
{mfargs,{net_kernel,start_link,
[[api#,longnames],true,net_sup]}},
{restart_type,permanent},
{significant,false},
{shutdown,2000},
{child_type,worker}]
=CRASH REPORT==== 2-Apr-2022::16:20:30.960246 ===
crasher:
initial call: net_kernel:init/1
pid: <0.3363.0>
registered_name: []
exception exit: {error,badarg}
in function gen_server:init_it/6 (gen_server.erl, line 407)
ancestors: [net_sup,kernel_sup,<0.3349.0>]
message_queue_len: 0
messages: []
links: [<0.3360.0>]
dictionary: [{longnames,true}]
trap_exit: true
status: running
heap_size: 987
stack_size: 28
reductions: 770
neighbours:
=SUPERVISOR REPORT==== 2-Apr-2022::16:20:30.963246 ===
supervisor: {local,kernel_sup}
errorContext: start_error
reason: {shutdown,
{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}
offender: [{pid,undefined},
{id,net_sup},
{mfargs,{erl_distribution,start_link,[]}},
{restart_type,permanent},
{significant,false},
{shutdown,infinity},
{child_type,supervisor}]
=CRASH REPORT==== 2-Apr-2022::16:20:30.966821 ===
crasher:
initial call: application_master:init/4
pid: <0.3348.0>
registered_name: []
exception exit: {{shutdown,
{failed_to_start_child,net_sup,
{shutdown,
{failed_to_start_child,net_kernel,
{'EXIT',nodistribution}}}}},
{kernel,start,[normal,[]]}}
in function application_master:init/4 (application_master.erl, line 142)
ancestors: [<0.3347.0>]
message_queue_len: 1
messages: [{'EXIT',<0.3349.0>,normal}]
links: [<0.3347.0>,<0.3346.0>]
dictionary: []
trap_exit: true
status: running
heap_size: 610
stack_size: 28
reductions: 165
neighbours:
=INFO REPORT==== 2-Apr-2022::16:20:30.967283 ===
application: kernel
exited: {{shutdown,
{failed_to_start_child,net_sup,
{shutdown,
{failed_to_start_child,net_kernel,
{'EXIT',nodistribution}}}}},
{kernel,start,[normal,[]]}}
type: permanent
{"Kernel pid terminated",application_controller,"{application_start_failure,kernel,{{shutdown,{failed_to_start_child,net_sup,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}}},{kernel,start,[normal,[]]}}}"}
Kernel pid terminated (application_controller) ({application_start_failure,kernel,{{shutdown,{failed_to_start_child,net_sup,{shutdown,{failed_to_start_child,net_kernel,{'EXIT',nodistribution}}}}},{ker
Crash dump is being written to: erl_crash.dump...done
Process exited with status 1
State changed from starting to crashed
Let me know if theres specific info you need to help me narrow the problem down.
Anyone have any ideas?
I had a rel/env.sh.eex file that was setting
export RELEASE_DISTRIBUTION=name
export RELEASE_NODE=api#${POD_IP}
where POD_IP was not set, causing the error.
You should check your pc's os hostname. It should contain ".",otherwise long name can't be used.

How do I disable the error logger in EUnit test cases?

When running an EUnit test that tests an application or starts and stops (or tests killing of) gen_server or supervisor processs, error logger outputs crash reports and other messages by default:
$ rebar3 eunit 1s
===> Verifying dependencies...
===> Compiling my_app
===> Performing EUnit tests...
...........=INFO REPORT==== 5-Sep-2019::16:32:18.760457 ===
application: ranch
exited: stopped
type: temporary
=INFO REPORT==== 5-Sep-2019::16:32:18.760545 ===
application: xmerl
exited: stopped
type: temporary
=INFO REPORT==== 5-Sep-2019::16:32:18.763882 ===
application: my_app
exited: stopped
type: temporary
......=ERROR REPORT==== 5-Sep-2019::16:32:18.814431 ===
** Generic server my_app_sup terminating
** Last message in was {'EXIT',<0.279.0>,test_kill}
** When Server state == {state,
{local,my_app_sup},
simple_one_for_one,
{[undefined],
#{undefined =>
{child,undefined,undefined,
{my_app_server,start_link,[]},
transient,5000,worker,
[my_app_server]}}},
{maps,#{<0.355.0> => [my_app_test]}},
1,5,[],0,my_app_sup,[]}
** Reason for termination ==
** test_kill
=CRASH REPORT==== 5-Sep-2019::16:32:18.814598 ===
crasher:
initial call: supervisor:my_app_sup/1
pid: <0.354.0>
registered_name: my_app_sup
exception exit: test_kill
in function gen_server:decode_msg/9 (gen_server.erl, line 432)
ancestors: [<0.279.0>]
message_queue_len: 0
messages: []
links: []
dictionary: []
trap_exit: true
status: running
heap_size: 1598
stack_size: 27
reductions: 6463
neighbours:
...........
Finished in 0.457 seconds
28 tests, 0 failures
How can I avoid these expected messages during testing?
These can be avoided by temporarily disabling TTY reports in the error logger. Surround the code which produces the reports with this:
my_test() ->
error_logger:tty(false),
try
% code that produces error logger reports
after
error_logger:tty(true)
end.
If you use this many times in the tests, this wrapper can be useful:
without_error_logger(Fun) ->
error_logger:tty(false),
try
Fun()
after
error_logger:tty(true)
end.
Which is used like so:
without_error_logger(fun() ->
% code that produces error logger reports
end)

RabbitMQ crashed and remained in hung state

One of the RabbitMQ nodes went down but remained in hung state which didn't let the other node to become active node. Have a VIP through which applications connect to Rabbit, in case one of the nodes go down the VIP switches to the other node but this didn't happen as the first node, that went down, hung itself.
Below are the logs from that time.
[Then Active Node that hung]
=CRASH REPORT==== 11-Jun-2017::05:15:09 ===
crasher:
initial call: rabbit_disk_monitor:init/1
pid: <0.253.0>
registered_name: rabbit_disk_monitor
exception exit: {eagain,[{erlang,open_port,
[{spawn,"/bin/sh -s unix:cmd 2>&1"},
[stream]],
[]},
{os,start_port_srv_handle,1,
[{file,"os.erl"},{line,313}]},
{os,start_port_srv_loop,0,
[{file,"os.erl"},{line,329}]}]}
in function gen_server:terminate/7 (gen_server.erl, line 826)
ancestors: [rabbit_disk_monitor_sup,rabbit_sup,<0.243.0>]
messages: []
links: [<0.252.0>]
dictionary: []
trap_exit: false
status: running
heap_size: 1598
stack_size: 27
reductions: 2036096302
neighbours:
[The other node which should have taken over]
=CRASH REPORT==== 11-Jun-2017::05:15:09 ===
crasher:
initial call: rabbit_disk_monitor:init/1
pid: <0.253.0>
registered_name: rabbit_disk_monitor
exception exit: {eagain,[{erlang,open_port,
[{spawn,"/bin/sh -s unix:cmd 2>&1"},
[stream]],
[]},
{os,start_port_srv_handle,1,
[{file,"os.erl"},{line,313}]},
{os,start_port_srv_loop,0,
[{file,"os.erl"},{line,329}]}]}
in function gen_server:terminate/7 (gen_server.erl, line 826)
ancestors: [rabbit_disk_monitor_sup,rabbit_sup,<0.243.0>]
messages: []
links: [<0.252.0>]
dictionary: []
trap_exit: false
status: running
heap_size: 1598
stack_size: 27
reductions: 2036096302
neighbours:
Could, using delayed message plugin and mnesia have caused this?
eagain means Resource temporarily unavailable
Most likely you ran out the filedescriptors.
Check your current filedescription configuration and try to increase it
Check this links for more details:
debian: http://www.rabbitmq.com/install-debian.html#kernel-resource-limits
RPM http://www.rabbitmq.com/install-rpm.html#kernel-resource-limits

Erlang: Mnesia can not create schema while release with rebar

When I call mnesia:create_schema on startup, the program crashes.
If I run my program in ebin without releasing it, it works find.
The error log as follows:
=INFO REPORT==== 3-Jul-2013::09:44:06 ===
application: eddy
exited: {bad_return,
{{eddy_app,start,[normal,[]]},
{'EXIT',
{{badmatch,
{error,
{'EXIT',
{undef,
[{mnesia_backup,open_write,
["/home/cometeor/eddy/rel/eddy/Mnesia.eddy#127.0.0.1/eddy#127.0.0.1137284464686415846847780"],
[]},
{mnesia_bup,do_apply,4,
[{file,"mnesia_bup.erl"},{line,387}]},
{mnesia_bup,make_initial_backup,3,
[{file,"mnesia_bup.erl"},{line,378}]},
{mnesia_bup,create_schema,2,
[{file,"mnesia_bup.erl"},{line,348}]},
{eddy_database,start,0,
[{file,"src/eddy_database.erl"},{line,24}]},
{eddy_app,start,2,[{file,"src/eddy_app.erl"},{line,16}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},{line,274}]}]}}}},
[{eddy_database,start,0,
[{file,"src/eddy_database.erl"},{line,24}]},
{eddy_app,start,2,[{file,"src/eddy_app.erl"},{line,16}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},{line,274}]}]}}}}
Resolved.Must add
{app, mnesia, [{mod_cond, app}]},
to reltool.config.

Erlang application undef error (exited: {bad_return,)

I am trying to run a custom application but get multiple errors. I believe the main egs app gets an error because it calls the egs patch app which has an undefined type. I cant figure out how to get this working I have tried recompiling the code many times in regards to others with a similar problem but nothing seems to work. The cowboy start listener remains undefined.
This is the error I receive.
=CRASH REPORT==== 10-Apr-2013::21:02:00 ===
crasher:
initial call: application_master:init/4
pid: <0.106.0>
registered_name: []
exception exit: {bad_return,
{{egs_patch_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{patch,11030},
10,cowboy_tcp_transport,
[{port,11030}],
egs_patch_protocol,[]],
[]},
{egs_patch_app,start_listeners,1,
[{file,"src/egs_patch_app.erl"},
{line,44}]},
{egs_patch_app,start,2,
[{file,"src/egs_patch_app.erl"},
{line,31}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
in function application_master:init/4 (application_master.erl, line 138)
ancestors: [<0.105.0>]
messages: [{'EXIT',<0.107.0>,normal}]
links: [<0.105.0>,<0.7.0>]
dictionary: []
trap_exit: true
status: running
heap_size: 610
stack_size: 27
reductions: 124
neighbours:
=INFO REPORT==== 10-Apr-2013::21:02:00 ===
application: egs_patch
exited: {bad_return,
{{egs_patch_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{patch,11030},
10,cowboy_tcp_transport,
[{port,11030}],
egs_patch_protocol,[]],
[]},
{egs_patch_app,start_listeners,1,
[{file,"src/egs_patch_app.erl"},{line,44}]},
{egs_patch_app,start,2,
[{file,"src/egs_patch_app.erl"},{line,31}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
type: temporary
=CRASH REPORT==== 10-Apr-2013::21:02:00 ===
crasher:
initial call: application_master:init/4
pid: <0.75.0>
registered_name: []
exception exit: {bad_return,
{{egs_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{login,12030},
10,cowboy_ssl_transport,
[{port,12030},
{certfile,"priv/ssl/servercert.pem"},
{keyfile,"priv/ssl/serverkey.pem"},
{password,"alpha"}],
egs_login_protocol,[]],
[]},
{egs_app,start_login_listeners,1,
[{file,"src/egs_app.erl"},{line,55}]},
{egs_app,start,2,
[{file,"src/egs_app.erl"},{line,38}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
in function application_master:init/4 (application_master.erl, line 138)
ancestors: [<0.74.0>]
messages: [{'EXIT',<0.76.0>,normal}]
links: [<0.74.0>,<0.7.0>]
dictionary: []
trap_exit: true
status: running
heap_size: 987
stack_size: 27
reductions: 185
neighbours:
=INFO REPORT==== 10-Apr-2013::21:02:00 ===
application: egs
exited: {bad_return,
{{egs_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener,
[{login,12030},
10,cowboy_ssl_transport,
[{port,12030},
{certfile,"priv/ssl/servercert.pem"},
{keyfile,"priv/ssl/serverkey.pem"},
{password,"alpha"}],
egs_login_protocol,[]],
[]},
{egs_app,start_login_listeners,1,
[{file,"src/egs_app.erl"},{line,55}]},
{egs_app,start,2,
[{file,"src/egs_app.erl"},{line,38}]},
{application_master,start_it_old,4,
[{file,"application_master.erl"},
{line,274}]}]}}}}
type: temporary
Here are the files from which the errors originate.
egs_patch_app.erl
-module(egs_patch_app).
-behaviour(application).
-export([start/2, stop/1]). %% API.
-type application_start_type()
:: normal | {takeover, node()} | {failover, node()}.
%% API.
-spec start(application_start_type(), term()) -> {ok, pid()}.
start(_Type, _StartArgs) ->
{ok, PatchPorts} = application:get_env(patch_ports),
start_listeners(PatchPorts),
egs_patch_sup:start_link().
-spec stop(term()) -> ok.
stop(_State) ->
ok.
%% Internal.
-spec start_listeners([inet:ip_port()]) -> ok.
start_listeners([]) ->
ok;
start_listeners([Port|Tail]) ->
{ok, _Pid} = cowboy:start_listener({patch, Port}, 10,
cowboy_tcp_transport, [{port, Port}],
egs_patch_protocol, []),
start_listeners(Tail).
egs_app.erl
-module(egs_app).
-behaviour(application).
-export([start/2, stop/1]). %% API.
-include("/home/mattk/Desktop/egs-master/apps/egs/include/records.hrl").
-type application_start_type()
:: normal | {takeover, node()} | {failover, node()}.
-define(SSL_OPTIONS, [{certfile, "priv/ssl/servercert.pem"},
{keyfile, "priv/ssl/serverkey.pem"}, {password, "alpha"}]).
%% API.
-spec start(application_start_type(), term()) -> {ok, pid()}.
start(_Type, _StartArgs) ->
{ok, Pid} = egs_sup:start_link(),
application:set_env(egs_patch, patch_ports, egs_conf:read(patch_ports)),
application:start(egs_patch),
start_login_listeners(egs_conf:read(login_ports)),
{_ServerIP, GamePort} = egs_conf:read(game_server),
{ok, _GamePid} = cowboy:start_listener({game, GamePort}, 10,
cowboy_ssl_transport, [{port, GamePort}] ++ ?SSL_OPTIONS,
egs_game_protocol, []),
{ok, Pid}.
-spec stop(term()) -> ok.
stop(_State) ->
ok.
%% Internal.
-spec start_login_listeners([inet:ip_port()]) -> ok.
start_login_listeners([]) ->
ok;
start_login_listeners([Port|Tail]) ->
{ok, _Pid} = cowboy:start_listener({login, Port}, 10,
cowboy_ssl_transport, [{port, Port}] ++ ?SSL_OPTIONS,
egs_login_protocol, []),
start_login_listeners(Tail).
Here's our hint:
.....
{{egs_patch_app,start,[normal,[]]},
{'EXIT',
{undef,
[{cowboy,start_listener, .....
The tuple {egs_patch_app,start,[normal,[]]} tells us that the error occurred in egs_patch_app:start/2. The atom EXIT is the tag of a notification message sent when a process has exited, or the result of an expression like catch error(someerror). Now we get to the interesting part. undef means an attempt was made to call an undefined function. A function is undefined if its Name/Arity doesn't match any known function. In this case, the undefined function is cowboy:start_listener().
Once again, the problem is that Cowboy has evolved while egs has not. Major changes in the Cowboy API have made the two incompatible. Since the last change in egs was about a year ago (assuming you're using essen's branch), you could try reverting to an older Cowboy tag by changing the corresponding rebar.config line to something like this:
{cowboy, ".*", {git, "git://github.com/extend/cowboy.git", {tag, "0.6.0"}}
Notice how "HEAD" changed to {tag, "0.6.0"}. The Cowboy reference may have to be changed in several applications (at least egs and egs_patch). You'll quite possibly need to clear your deps/ first.
Erlang error messages can be difficult to parse, but as a general rule of thumb, you should be on the lookout for a few atoms:
case_clause, meaning no clause in a case expression matched.
function_clause, meaning no function clause matched the arguments.
undef, as noted above, meaning a call to an external (not local to module) function couldn't be resolved.
badarg, which is Erlang's "illegal argument" exception.
badarith, a sneaky bastard that sometimes shows up when you mistype a variable name as an atom in an arithmetic expression, such as 1/x instead of 1/X.
To learn more about Erlang's error handling mechanisms, read the docs.

Resources