Erlang: Why don't I see error_logger:info_msg output when connected by remsh? - erlang

I connect to a running node with the -remsh flag, and I run my usual Common Test sanity tests, but none of the error_logger:info_msg messages appear in the shell. Why?

The SASL default event handler will only write events to console/tty of the local node.
When connecting via "-remsh", you're starting a second node and communicating via
message passing to the first. The output from the "nodes()" BIF can confirm this.
Calls to the error_logger functions will send events to the local 'error_logger'
registered process, which is a gen_event server. You can manipulate it using
error_logger:tty/1 and error_logger:logfile/1, see the reference docs in the "Basic"
Application Group, then the "kernel" application, then the "error_logger" module.
You can also add your own event handler to the 'error_logger' server, which can then
do anything you want with the event. I'd guess that error_logger:logfile/1 might be
sufficient for your purposes, though.
-Scott

Related

How do I handle the death of another node in Erlang?

I have two nodes that are connected to each other, where one of them is the server. The server would like to know if the client dies. I did something like this:
link(Client).
In the server process, and when I did that I receive a exception error: noconnection and then the server dies, when the client dies. I would just like to know if the client dies, I do not want the server do die, how do I handle the death message?
If you have two erlang nodes and want to take some actions in case if one node goes down (or network connection is lost) you possible want to use erlang:monitor_node/2,3 functions:
(n1#myhost)1> erlang:monitor_node('n2#myhost', true).
true
then if 'n2#myhost' node goes down your process will receive message:
(n1#myhost)2> flush().
Shell got {nodedown,n2#myhost}
(note, I did that from erlang shell, that is why I may call flush/0 to see what is in the mailbox of the shell process)
If you interested in certain process, on the second node you may use erlang:monitor/2
(n1#myhost)3> Ref = erlang:monitor(process, {'n2#myhost', some_registered_name}).
#Ref<0.0.0.117>
from now you will receive a message if some_registered_name goes down and you can take an action.
Also you may be interested in how to write distributed applications
To have unidirectional supervision, you should use monitors. Then your server will receive a message if the client dies.

Windows Proc "Unavailable" for processes spawned by service

I'm attempting to use psexec to spawn a process on a remote machine (for automated testing purposes) and noticed that the spawned process wasn't correctly responding to a message (WM_GETOBJECT, but that's another question entirely). I opened spy++ in an attempt to see why, but I couldn't log any messages going to my process' window. The window properties also indicated that the "Windows Proc" for the window was "Unavailable":
.
I think this is a behavior of Windows services since psexec uses an embedded service on the remote machine to launch the requested application. I was logged onto both machines with the same credentials so I don't believe it is a user security issue but rather a service-related behavior.
As a sanity check I wrote a quick standalone server and client to execute a program remotely and everything worked as expected: the Window Proc was no longer "unavailable" and I could spy on messages.
I used the normal Windows Calculator (calc) for all my tests, i.e.:
psexec.exe -i \\other-machine calc
My question: Can someone confirm, explain, and/or cite why I can't see message queues of processes spawned off services? Also is there a workaround to this? I'd rather use psexec than my custom solution. Bonus if you can also explain why WM_GETOBJECT doesn't return my custom UI Automation provider in this situation as well, as that's my original problem.

Detecting failure at runtime?

1) Is there a way to automatically detect when a node fails, from another node?
2) Is there a way to automatically re-start the node which just crashed?
Regarding my second question, I have googled about and I cannot see to find any mention to creating nodes from code/at runtime.
I understand you can do this with processes- creating processes at runtime is trivial and if you want to know when they crash you can create them from a supervisor etc- but I cant find anything relating to node detection/creation.
Need this for a client who wish to design a smaller version of Amazon EDS, but I cannot imagine Amazon manually restarting nodes if they go down!
You can make use of net_kernel:monitor_nodes(true, [{node_type, visible}]) to monitor all visible nodes from inside your erlang application. From man page:
The calling process subscribes or unsubscribes to node status change
messages. A nodeup message is delivered to all subscribing process
when a new node is connected, and a nodedown message is delivered when
a node is disconnected.
I don't see any straight forward method (from inside your process which receives nodedown message) using which you can start a node on remote machine. You will probably need to write a small module which do this for you automatically.

Threaded Erlang C-Node(cnode) Interoperability howto?

I am at a point in my Erlang development where I need to create a C-Node (see link for C-Node docs). The basic implementation is simple enough, however, there is a huge hole in the doc.
The code implements a single threaded client and server. Ignoring the client for the moment... The 'c' code that implements the server is single threaded and can only connect to one erlang client at a time.
Launch EPMD ('epmd -daemons')
Launch the server application ('cserver 1234')
Launch the erlang client application ('erl -sname e1 -setcookie secretcookie') [in a different window from #2]
execute a server command ('complex3:foo(3).') from the erlang shell in #3
Now that the server is running and that a current erlang shell has connected to the server try it again from another window.
open a new window.
launch an erlang client ('erl -sname e2 -setcookie secretcookie').
execute a new server command ('complex3:foo(3).').
Notice that the system seems hung... when it should have executed the command. The reason it is hung is because the other erlang node is connected and that there are no other threads listening for connections.
NOTE: there seems to be a bug in the connection handling. I added a timeout in the receive block and I caught some errant behavior but I did not get them all. Also, I was able to get the cserver to crash without warnings or errors if I forced the first erlang node to terminate after the indicated steps were performed.
So the question... What is the best way to implement a threaded C-Node? What is a reasonable number of connections?
The cnode implementation example in the cnode tutorial is not meant to handle more than one connected node, so the first symptom you're experiencing is normal.
The erl_accept call is what accepts incoming connections.
if ((fd = erl_accept(listen, &conn)) == ERL_ERROR)
erl_err_quit("erl_accept");
fprintf(stderr, "Connected to %s\n\r", conn.nodename);
while (loop) {
got = erl_receive_msg(fd, buf, BUFSIZE, &emsg);
Note that, written this way, the cnode will accept only one connection and then pass the descriptor to the read/write loop. That's why when the erlang node closes, the cnode ends with an error, since erl_receive_msg will fail because fd will point to a closed socket.
If you want to accept more than one inbound connection, you'll have to loop accepting connections and implement a way to handle more than one file descriptor. You needn't a multithread programme to do so, it would probably be easier (and maybe more efficient) to use the poll or select syscall if your OS supports them.
As for the optimum number of connections, I don't think there is a rule for that, you'd need to benchmark your application if you want to support high concurrency in the cnode. But in that case it would probably be better to re-engineer the system so that erlang copes with the concurrency, alleviating the cnode from that.

TService won’t process messages

I have created a windows service that uses Windows Messaging System. When I test the app from the debugger the Messages go through nicely but when I install it my messag … asked 14 mins ago
vladimir
1tuga
Services don't generally receive window messages. They don't necessarily have window handles at all. Even if they do, they run in a separate desktop. Programs cannot send messages from one desktop to another, so a service can only receive messages from another service, or from a program started by a service.
Before Windows Vista, you could have configured your service to interact with the desktop. That makes the service run on the same desktop as a logged-in user, so a program running as that user could send messages to your service's windows. Windows Vista isolates services, though; they can't interact with any user's desktop anymore.
There are many other ways to communicate with services. They include named pipes, mailslots, memory-mapped files, semaphores, events, and sockets.
With a socket, for instance, your service could listen on an open port, and programs that need to communicate with it could connect to that port. This could open the door to remote administration, but you can also restrict the service to listen only for local connections.
All the above is trying to tell you that you're taking the wrong approach. But there's also the matter of the problem at hand. Your program behaves one way in the debugger and another way outside it. How are you debugging the service in the first place, if it's not installed? What user account is your service running as? Your debugger? What debugging techniques have you tried that don't involve the debugger (e.g. writeln to a log file to track your program's actions)?
What do you mean when you say it "uses" Windows Messaging System? Are you consuming or sending Windows Messages?
If you send a Windows message, you need ensure you are doing it correctly. I'd suggest writing a message loop to ensure your messages are being dispatched properly. I'd also suggest reading up on message loops and how they work.
What is a Message Loop (click the title to be taken to the source of this info)
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
The message loop calls GetMessage(),
which looks in your message queue.
If the message queue is empty your
program basically stops and waits
for one (it Blocks).
When an event occures causing a
message to be added to the queue
(for example the system registers a
mouse click) GetMessages() returns a
positive value indicating there is a
message to be processed, and that it
has filled in the members of the MSG
structure we passed it. It returns 0
if it hits WM_QUIT, and a negative
value if an error occured.
We take the message (in the Msg
variable) and pass it to
TranslateMessage(), this does a bit
of additional processing,
translating virtual key messages
into character messages. This step
is actually optional, but certain
things won't work if it's not there.
Once that's done we pass the message
to DispatchMessage(). What
DispatchMessage() does is take the
message, checks which window it is
for and then looks up the Window
Procedure for the window. It then
calls that procedure, sending as
parameters the handle of the window,
the message, and wParam and lParam.
In your window procedure you check
the message and it's parameters, and
do whatever you want with them! If
you aren't handling the specific
message, you almost always call
DefWindowProc() which will perform
the default actions for you (which
often means it does nothing).
Once you have finished processing
the message, your windows procedure
returns, DispatchMessage() returns,
and we go back to the beginning of
the loop.
Thank you all for the answers,
the issue was the operating system (vista), i tested the with my windows 2000 and everything works.
thanks for the light Rob.

Resources