An error with Erlang router - erlang

I try to make a comet-server using Mochiweb like there.
If I do it from erlang shell, it's alright.
But If try to start 1st node with mochiweb from command line:
erl -pa ebin edit deps/*/ebin -boot start_sasl -sname n1 -s server +K true -setcookie secret_key -s reloader
And 2nd one with router:
erl -pa ebin edit deps/*/ebin -boot start_sasl -sname router -setcookie secret_key -eval 'net_adm:ping(n1#localhost), router:start_link().'
If I connect to mochiweb from browser I have this error
=CRASH REPORT==== 18-Jul-2012::19:04:45 ===
crasher:
initial call: mochiweb_acceptor:init/3
pid: <0.73.0>
registered_name: []
exception exit: {noproc,
{gen_server,call,
[undefined,{login,"234567e",<0.73.0>}]}}
in function gen_server:call/2
in call from server_web:loop/2
in call from mochiweb_http:headers/5
ancestors: [server_web,server_sup,<0.55.0>]
messages: []
links: [<0.57.0>,#Port<0.1406>]
dictionary: [{mochiweb_request_qs,
[{"session_id","234567e"},{"obj_id","page"}]},
{mochiweb_request_path,"/polling"}]
trap_exit: false
status: running
heap_size: 2584
stack_size: 24
reductions: 1516
I think that problem is in this string from router.erl:
-define(SERVER, global:whereis_name(?MODULE)).
Because first part of -eval (net_adm:ping(n1#localhost)) was started without errors and I could see n1#localhost in nodes().. But the second part of -eval (router:start_link()) was not available for ?MODULE.
How can I resolve this problem?

Looks like the gen_server that was supposed to be globally registered with name of current module (?MODULE is replaced with it) just has not been started yet. global:whereis_name(?MODULE) will return undefined right in this case, like you see in log you posted.
Find the part of your code that's supposed to do that (by grepping for ?MODULe and/or gen_server:start_link in that module) and make sure it was executed on the first node.

Related

cannot start empty OTP application from command line

I have created an OTP application skeleton with rebar:
$ rebar create-app appid=test
then I compiled it with rebar compile, and when I run
$ erl -pa ebin -s test
I get this error
{"init terminating in do_boot",{undef,[{test,start,[],[]},{init,start_it,1,[]},{init,start_em,1,[]}]}}
but if I call start from the shell it works:
$ erl -pa ebin
Erlang R15B01 (erts-5.9.1) [source] [smp:2:2] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.9.1 (abort with ^G)
1> application:start(test).
ok
How can I start the application from the OS command line?
EDIT:
I figured that I needed to run
$ erl -pa ebin -s application start test
now I am not getting any errors, but the app is still not getting started...
erl -pa ebin/ -eval "application:start(test)"
Since the start function in test_app.erl has arity 2 it is not possible to invoke it directly using the erl switch -s (or -run), only arity 0 or 1 are possible to invoke with those switches (see http://erlang.org/doc/man/erl.html).
You could add a wrapper function that in turn calls the start/2, but I think the -eval is more elegant.
The -s flag assumes a list of arguments when one or more arguments are presented. So what $ erl -pa ebin -s application start test would do is calling application:start([test]) which would not work as expected.
Here is a workaround (might not be the best solution):
Create a source file src/test_init.erl with the following content:
-module(test_init).
-compile(export_all).
init() ->
application:start(test).
Then:
$ rebar compile
$ erl -pa ebin -s test_init init
Now the test application should be running:)

How to run erlang (rebar build) application

I am new to Erlang world and currently can't figure out how to start my dummy erlang application. Probably, I am just missing something... So, I created an application with rebar (rebar create-app appid=dummys).
Currently I have
rebar.config
src/dummys.app.src
src/dummys_app.erl
src/dummys_sup.erl
I have found that in order to run an application during a development it is better to create an additional start method which should call application:start(module).
I added some basic logging to my start methods..
start() ->
error_logger:info_msg("Starting app(dev)..~n"),
application:start(dummys_app).
start(_StartType, _StartArgs) ->
error_logger:info_msg("Starting app..~n"),
dummys_sup:start_link().
If I try
erl -noshell -pa ebin -s application start dummys
erl -noshell -pa ebin -s application start dummys_app
there are no output..
If I try
erl -noshell -pa ebin -s dummys start
erl crashes with an error..
If I try
erl -noshell -pa ebin -s dummys_app start
it outputs just "Starting app(dev).." and that's all. But I also expect to see "Starting app.."
What I am missing or doing wrong??
=============
And another question: How to add a new module to my dummy application correctly? For example I have an additional module called "*dummys_cool*" which has a "start" method. How to tell my application to run that "dummys_cool#start" method?
Thank you!
For quick development, if you just want to ensure your appliction can start, start a shell, then start the application:
erl -pa ebin
1> dummys_app:start().
That will give you a clean indication of what is wrong and right without the shell bombing out after.
Since you're making an application to run, rather than just a library to share, you'll want to make a release. Rebar can get you most of the way there:
mkdir rel
cd rel
rebar create-node nodeid=dummysnode
After you've compiled your application, you can create a release:
rebar generate
This will build a portable release which includes all the required libraries and even the erlang runtime system. This is put by default in the rel/ directory; in your case rel/dummys.
Within that directory there will be a control script that you can use to start, stop, and attach to the application:
rel/dummys/bin/dummys start
rel/dummys/bin/dummys stop
rel/dummys/bin/dummys start
rel/dummys/bin/dummys attach
Have a look at your dummys.app.src file. The meaning of all the directives is explained in the 'app' manpage, but the one I suspect is missing here is mod, which indicates the name of your application callback module. So make sure that this line is present:
{mod, {dummys_app, []}}
The empty list in there will be passed as the StartArgs argument to dummys_app:start/2.
To make a new module start along with your application, add it to the supervision tree in dummys_sup:init. This function should look something like:
init(_) ->
{ok, {{one_for_one, 10, 10},
[{dummys_cool, {dummys_cool, start_link, []},
permanent, brutal_kill, worker, [dummys_cool]}]}.
This is described in the 'supervisor' manpage, but basically this means that on startup, this supervisor will start one child process. dummys_cool:start_link() will be called, and that function is expected to spawn a new process, link to it, and return its process id. If you need more processes, just add more child specifications to the list.
erl -noshell -pa ebin -s application start dummys
The code above will not work because application:start([dummys]) will be called.
You can take a reference of the Erlang documentation for details.
For your case,
erl -noshell -pa ebin -s dummys
I ran into this problem, and this was the first answer on Google.
If you are using rebar3, the standard configuration will have a shell command that compiles your project and opens a shell:
$ rebar3 shell
===> Analyzing applications...
===> Compiling myapp
Erlang/OTP 21 [erts-10.2.4] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1]
Eshell V10.2.4 (abort with ^G)
1> ===> Booted myapp

Distributed Erlang: Learn about remote host and start function

I am trying to implement a really simple example to get a first look into Distributed Erlang. So, I start two nodes on the same machine:
erl -sname dilbert
erl -sname dogbert
The task is that dogbert makes dilbert output Hello, World! using a simple fun () -> io:format("Hello, World!") end on node dilbert. I thought this would be easy with dogbert's shell:
(dogbert#centraldogma.fubar)1> spawn(dilbert, fun () -> io:format("HELLO!") end).
<0.39.0>
=ERROR REPORT==== 13-Jun-2012::17:49:04 ===
** Can not start erlang:apply,[#Fun<erl_eval.20.82930912>,[]] on dilbert **
In the same shell, using nodes(). outputs []. Well, dogbert obviously doesn't know about dilbert, but why is that the case? Or, how do I make nodes in distributed erlang get to know each other?
There are two problems:
You must set a common cookie for both nodes so they can interact.
erl -sname dilbert -setcookie pointyhairedboss
erl -sname dogbert -setcookie pointyhairedboss
You must specify the hostname of the node you want to connect to.
spawn('dogbert#yourhostname', fun () -> io:format("HELLO!") end).

{error,{not_started,ibrowse}} when using couchbeam

by this document http://benoitc.github.com/couchbeam/
application:start(sasl),
application:start(ibrowse),
application:start(couchbeam).
When I run the code, it shows:
=PROGRESS REPORT==== 1-Mar-2012::10:16:57 ===
application: crypto
started_at: nonode#nohost
{error,{not_started,ibrowse}}
I want to do know how to make application:start(ibrowse),work, thanks!
According to your error message "started_at: nonode#nohost", I think that it may be caused by your erlang configuration file error.
Have you set up ".erlang.cookie" file, and is the file owner mode is exclusive? Only owner is allowed to read or write?
You can check your problem by inputting the command "erl -sname aaa"? Is output "nonode#nohost"?
It works by erl -pz ibrowse/ebin/
I fixed it with:
erl -pa ebin -pa deps/ibrowse/ebin -s couchbeam

Erlang VM -s argument misbehaving

When I start up a function within the erl shell, it works fine. When I try to invoke the same function with erl ... -s module function, it fails.
The line of code that eventually fails is:
start(Port) ->
mochiweb_http:start([{port, Port}, {loop, fun dispatch_requests/1}]).
I'm positive that Port is set correctly. My error message is:
=CRASH REPORT==== 17-Jan-2010::00:21:09 ===
crasher:
initial call: mochiweb_socket_server:acceptor_loop/1
pid: <0.65.0>
registered_name: []
exception exit: {error,closed}
in function mochiweb_socket_server:acceptor_loop/1
ancestors: [mochiweb_http,<0.1.0>]
messages: []
links: []
dictionary: []
trap_exit: false
status: running
heap_size: 377
stack_size: 24
reductions: 93
neighbours:
I tried the debugger and it lets me step through right up until the line of code above is given. After I pass that, it gives me this crash report.
Any help is greatly appreciated.
Hm, I think that should work.
Are all modules compiled with the same compiler version? IIRC there might be weird errors on the socket level if not.
BTW, you might call your entry point function start which is the default for -s.
Alternatively you can try the -eval option:
erl -eval 'module:start(9090).'
when using -s, the arguments are collected into a list, so the port would actually be enclosed in a list. you can check both cases (list or int) with a wrapper function (like start([Port])).
When you use -s to run Erlang functions, arguments are put into a list of atoms. When you use -run to run Erlang functions, arguments are put into a list of strings.
If you need an integer value to pass on, you will need to do the proper conversions. If you want to cover all cases, something like this could help:
start([Port]) when is_atom(Port) ->
start([atom_to_list(Port)]);
start([Port]) when is_list(Port) ->
start(list_to_integer(Port));
start(Port) when is_integer(Port) ->
mochiweb_http:start([{port, Port}, {loop, fun dispatch_requests/1}]).
Consult the man page for erl ("erl -man erl") for details.

Resources