use "exit/2" function in erlang shell - erlang

Three erlang processes have been created in erlang shell and registered locally, named Pid, Pid2, Pid3. Then I want to terminate "Pid" firstly by function "exit/2".
(emacs#yus-iMac.local)62> exit(lsaaa_dispatch,test). %lsaaa_dispatch is the above Pid's local registered name
** exception error: bad argument
in function exit/2
called as exit(lsaaa_dispatch,test)
Why exception happens?
And why all the three process are terminate? Because I can't find them in Pman.

exit/2 accepts a pid, not a term. And it's defined by the kernel 'erlang' module.
exit(whereis(lsaaa_dispatch), test).
Of your second question, think of the relationship these processes have with your shell.

Related

Unable to spawn process on another node in Erlang

When I try to create a new process on separate node using
Pid = spawn(mynode, mymodule, myfunction, [self()])
(myfunction/1 is exported), I get this error:
Error in process <0.10.0> on node 'no#de1' with exit value:
{undef,[{mymodule, myfunction, [<33.64.0>], []}]}
I tried to set -compile(export_all) flag, but assuming the additional braces in error log, this is not the case.
I don't know what causes the error and I have no clue what to do.
The error you get is saying “There is no module ‘mymodule’ and/or no function ‘mymodule:myfunction/1’”.
This means mymodule is not loaded in the code server of your separate node.
To load mymodule's code there you need something like this snippet or this function
Did you check that the module mymodule is in the path of no#de1?
When you spwan a process using spawn(mynode, mymodule, myfunction, [self()]), the VM needs to load the code before executing it.
If you use a high order function (a fun) in this way spawn(Node, Fun), then in is not more necessary to have the code in the path (but beware that any call to a function in the function definition need to be solved on the remote node)
go to no#de1 and run m(mymodule). It should clarify if the module is loadable and which functions does export.
also: check if the other node is reachable. Do a net_adm:ping on it.

Register and spawn_link in Erlang not working together

I have a process running on node2. Can I register this process using register/2 on node1? Basically I am trying to do this:
register(process_name, spawn_link(node2, module, function, [Arg1, Arg2]))
I get this error:
** exception error: bad argument
in function register/2
called as register(process_name, <5902.92.0>)
When I register a process local to node1, this works perfectly fine. I could not find any documentation which prevents registration of processes of other nodes.
Thanks.
Actually it is well documented, and the expected behaviour as register() is for local process registration.
http://www.erlang.org/doc/man/erlang.html#register-2
Failure: badarg if PidOrPort is not an existing, local process or port, [...]
If you want global registration across your cluster, read http://erlang.org/doc/man/global.html
Note that if you use standard OTP behaviours, (gen_server, etc) most of the time you don't need to use the global module directly.

Erlang: Send message to module?

I was reading this section in "Learn you some Erlang" and there's a piece of code that looks like:
start() ->
register(?MODULE, Pid=spawn(?MODULE, init, [])),
Pid.
start_link() ->
register(?MODULE, Pid=spawn_link(?MODULE, init, [])),
Pid.
terminate() ->
?MODULE ! shutdown.
I'm super confused by the terminate function. Does that say to send a message to the module itself? How does that work? What's going on?
TL;DR: shutdown is being sent to a process, not the module.
?MODULE is a value that, at compile time, is changed to the name of the current module (file).
What specifically is happening in this sample of code is that the process that is being spawned is being registered with the VM under the name of the module so that other processes can refer to it that way. You could replace ?MODULE in that entire block of code with nearly any atom at all, as long as you gave the same value each time.
So when terminate() is invoked, the shutdown message is not sent to the module, but rather to the process that was spawned and been registered under that name with the VM.
Using ?MODULE is merely a convenient approach for avoiding naming conflicts with other registered processes.

Default process flags

Is there a way to instruct the Erlang VM to apply a set of process flags to every new process that is spawned in the system?
For example in testing environment I would like every process to have save_calls flag set.
One way for doing this is to combine the Erlang tracing functionalities with a .erlang file.
Specifically, you could either use the low-level tracing capabilities provided by erlang:trace/3 or you could simply exploit the dbg:tracer/2 function to create a new tracing process which executes your custom handler function every time a tracing message is received.
To automate things a bit, you could then create an Erlang Start Up File in the directory where you're running your code or in your home directory. The Erlang Start Up File is a special file, called .erlang, which gets executed every time you start the run-time system.
Something like the following should do the job:
% -*- Erlang -*-
erlang:display("This is automatically executed.").
dbg:tracer(process, {fun ({trace, Pid, spawn, Pid2, {M, F, Args}}, Data) ->
process_flag(Pid2, save_calls, Data),
Data;
(_Trace, Data) ->
Data
end, 100}).
dbg:p(new, [procs, sos]).
Basically, I'm creating a new tracing process, which will trace processes (first argument). I'm specifying an handler function to get executed and some initial data. In the handler function, I'm setting the save_calls flag for newly spawned processes, whilst I'm ignoring all other tracing messages. I set the save_calls' option to 100, using the Initial Data parameter. In the last call, I'm telling dbg that I'm interested only in newly created processes. I'm also setting the sos (set_on_spawn) option to ensure inheritance of the tracing flags.
Finally, note how you need to use a variant of the process_flag function, which takes an extra argument (the Pid of the process you want to set the flag for).

Erlang Takeover failing after successful Failover

I have an application distributed over 2 nodes. When I halt() the first node the failover works perfectly, but ( sometimes ? ) when I restart the first node the takeover fails and the application crashes since start_link returns already started.
SUPERVISOR REPORT <0.60.0> 2009-05-20 12:12:01
===============================================================================
Reporting supervisor {local,twitter_server_supervisor}
Child process
errorContext start_error
reason {already_started,<2415.62.0>}
pid undefined
name tag1
start_function {twitter_server,start_link,[]}
restart_type permanent
shutdown 10000
child_type worker
ok
My app
start(_Type, Args)->
twitter_server_supervisor:start_link( Args ).
stop( _State )->
ok.
My supervisor :
start_link( Args ) ->
supervisor:start_link( {local,?MODULE}, ?MODULE, Args ).
Both nodes are using the same sys.config file.
What am I not understanding about this process that the above should not work ?
It seems like your problem stem from twitter server supervisor trying to start one of its children. Since the error report complains about the child with start_function
{twitter_server,start_link,[]}
And since you are not showing that code, I can only guess that it is trying to register a name for itself, but there is already a process registered with that name.
Even more guessing, the reason shows a Pid, the Pid that has the name that we tried to grab for ourself:
{already_started,<2415.62.0>}
The Pid there has a non-zero initial integer, if it was zero it means it is a local process. From which I deduce that you are trying to register a global name, and you are connected to another node where there is already a process globally registered by that name.

Resources