What happens when link and monitor the same process in Erlang - erlang

If process A link to B and A monitor B, when B dies, what happens to A? will A receive two messages? one is monitor 'Down' message and the other is exit message from B, if it is, what's the order abd what will A do?

When links and monitors are triggered they send out signals - you can read about this in more detail here: https://www.erlang.org/doc/reference_manual/processes.html#signals
Looking at the BEAM emulator code, it turns out that the links are triggered before the monitors when a process dies - see erl_process.c: https://github.com/erlang/otp/blob/master/erts/emulator/beam/erl_process.c#L14149
I can't seem to find this fact documented anywhere, but I would guess it's to ensure that if process A doesn't trap exits, it gets killed immediately when the exit signal from process B arrives. If it got the monitor signal first, it might start acting on it but then get killed halfway through the action when the exit signal is received.

Related

NodeMCU resest with mqtt.client:close()), or mqtt.client:connect()

I have an application that uses mqtt for communication between modules and with a mobile terminal.
In some situations when the messages do not arrive, the node performs a self test of MQTT (sending a msg to itself), and when the selftest fails, tries to reconnect to the broker (mqtt offline not always arrives). And then two problems may arise:
If I perform a mqtt.client:close() to assure that the client is closed (to avoid the second problem) and the client is already closed, the node resets.
If I perform a mqtt.client:connect() and the client is still connected, an exception and a restet occurs.
is there a way to know if the mqtt client is connected or not?
Thanks for your comment. I am going to describe what I am doing, to see if you can help me:
I have two independent system, a master and a slave. The master publish a test message every 10 minutes. If there is no answer from the slave. it publish a test message to itself. If this self test does not arrive, a disconnection from the broker is assumed, and a reconnection is initiated.
And here is where the problem comes, sometimes the client is disconnected and everything go well, but sometimes it is still connected but unresponsive, and the node resets with an exception "already connected".
Performing a mqtt:close() previously to the reconnection, should be safe, but if I send it and the client is truly disconnected, the node resets without any reason (known to me).
All this is happening without receiving any offline message.
Instead of waiting for messages manually sent by the master client (which could fail to send for various reasons, leading a listening device to the wrong conclusion about the state of its connection to the broker), I recommend using MQTT's built-in connection management.
First, you can make sure that each client's initial connection has succeeded by including an error handler in :connect(). If the client really opens, nothing in the NodeMCU documentation indicates that it will close itself; it may go offline.
Once connected, the client only knows that something is wrong when it sends a message and does not receive a response. It sounds like you are not calling :publish() much (which would otherwise let you know by returning false), so pinging may be best. If you expect to receive a message from the broker every n seconds, set a keepalive time slightly higher than that on the client.
Then, failure to get a response to those messages should trigger an event that you can respond to. That might be something like the following (not tested, may work better called outside the callback):
m:on("offline", function(client) m:close() end)

Network code stopping with SIGPIPE

I am developing in iOS.
The App call the function in library , and send the packet via wifi.
When the App is running , I push the power button(not home button) on iPhone 5C and push again to open it. But it crash...
And it did not show which line is error , it only show the error like the following picture:
How to analyse this crash log via above picture?
Thanks in advance.
As mentioned by Apple, in Avoiding Common Networking Mistakes, you need to handle or disable SIGPIPE:
Use POSIX sockets efficiently (if at all).
If you are using POSIX sockets directly:
Handle or disable SIGPIPE.
When a connection closes, by default, your
process receives a SIGPIPE signal. If your program does not handle or
ignore this signal, your program will quit immediately. You can handle
this in one of two ways:
Ignore the signal globally with the following line of code:
signal(SIGPIPE, SIG_IGN);
Tell the socket not to send the signal in
the first place with the following lines of code (substituting the
variable containing your socket in place of sock):
int value = 1;
setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, &value, sizeof(value));
For maximum compatibility, you should set this flag on each incoming
socket immediately after calling accept in addition to setting the
flag on the listening socket itself.

Is the appPaused event working properly for me? I am getting some weird behavior with my clean-up code on iOS

I have been dealing with this issue for weeks and am unsure if it is my code's fault, forge's appPaused event not triggering quickly enough, or Trigger.io's documentation not being nearly clear enough about just how little time iOS gives us to execute clean-up code.
According to the documentation regarding the appPaused event:
iOS: A short amount of time is given for execution, it is generally best to assume that callbacks and timers may not fire until the app is resumed.
My application deals with websockets and ideally I am able to send a close event to my server when a user minimizes my app, or the phone is locked. Currently, all of my clean-up code runs perfectly on Android, but on iOS, my clean-up code doesn't run until the app is resumed. The strange part is sometimes (maybe 1 out of 20 times) the iOS clean-up is correctly run right after the appPaused event is fired.
To test this I have done two things:
I make the very first thing to run after the appPaused event is fired is a message to my websocket server saying "the app is paused". 95% of the time, this message is not actually sent until the app is resumed, but the other 5% of the time my websocket server receives it right after I pause the app.
I then made it so the first thing to run after the appPaused event is fired is a line that stores Date.now() in a global variable. I then then store Date.now() in another global variable when the app is resumed, and find the difference between them. It gets interesting because around 50% of the time the Date.now() line is correctly fired right after the appPaused event is called, but the other half of the time the 2 Date.now() calls are only milliseconds a part, proving that the clean-up code was not run until the app resumed.
So, can I really only expect to sometimes have enough time after appPaused is fired to even store Date.now() in a variable? Is this what everyone else is experiencing when running their Trigger.io applications on iOS? Let me know if anyone could use more information.
Yes, appPaused is not guaranteed to fire on iOS. Note, that it may only fire when the app is resumed.
Any code you want to run on going into the background will probably not run. See the trigger io docs on events. The note on iOS needs careful reading.
That said I have a similar app to yourself dealing in websockets. What i've found is that I can leave the socket open, iOS automatically kills the socket when it suspends the app (Sometime after the paused event is received which corresponds to the ios background state). The server receives the close event and you can of course attach to that event to set any state or cleanup resources. Android requires a manual shutdown of the socket, but appPaused works in a guaranteed way when the app is put into the background.

Wake a process from sleeping - Erlang

Is it possible to wake a process externally in Erlang after it has been sent to sleep for infinity?
I would like to wake it from a different process which does hold the process ID of the process which is asleep.
I used this within the process which I want to sleep:
timer:sleep(infinity)
If it is not possible to wake it externally, what other options are available to me?
Rather than using timer:sleep/1, put the process into a receive so that it waits for a message. When the other process wants it to proceed, it can simply send it a message. Assuming the message matches what the receive is looking for, the first process will then exit the receive and continue.
From the source code of this function:
-spec sleep(Time) -> 'ok' when
Time :: timeout().
sleep(T) ->
receive
after T -> ok
end.
you can find that sleep just let the process wait, do nothing.
if you want wake the process, you need send message to the sleeping process and do receive.

what does "exited abnormally with signal 9: Killed: 9" mean

How to read error codes which appear in the console?
<Warning>: ....... -exited abnormally with signal 9: Killed: 9
<Warning>: ....... -1 err = Bad file descriptor (0x00000009)
Here what does signal 9 mean, are there any more signals apart from it. Any documentation available for it.
I get this kind of error, when a App. launched from Xcode is terminated by "Stop" button in Xcode toolbar.
(Another way to get this error is , to press home button, then double tap home button and close the app.)
Things even get worse when I launch the App. again, by tapping on App. icon on iPad Screen, App crashes and throws "libMobileGestalt copySystemVersionDictionaryValue: Could not lookup ReleaseType from system version dictionary"
From finding on stack overflow , I see that this error is found in iOS 6 devices.
This url states that it's a SIGKILL error and it happens when "application is being terminated immediately, without any chance to clean up or catch and handle the signal"
So, I think releasing objets in -(void) didReceiveMemoryWarning would not help to solve it, then what could be a definite solution?
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release objects.
obj1 = nil;
[view1 removeFromSuperView];
view1 = nil;
...
}
It means that the application received a signal. Some signal could be handled by the applications, others, not. Signal 9 means that the application needs to be killed, it is not handled by the process, but by the Linux scheduler. The signal to terminate the process that is handled by the process is SIGTERM(15), but, if the process doesn't handle it property, then the process continues to live.
here are the major signals:
Signal Value Action Comment
──────────────────────────────────────────────────────────────────────
SIGHUP 1 Term Hangup detected on controlling terminal
or death of controlling process
SIGINT 2 Term Interrupt from keyboard
SIGQUIT 3 Core Quit from keyboard
SIGILL 4 Core Illegal Instruction
SIGABRT 6 Core Abort signal from abort(3)
SIGFPE 8 Core Floating point exception
SIGKILL 9 Term Kill signal
SIGSEGV 11 Core Invalid memory reference
SIGPIPE 13 Term Broken pipe: write to pipe with no
readers
SIGALRM 14 Term Timer signal from alarm(2)
SIGTERM 15 Term Termination signal
SIGUSR1 30,10,16 Term User-defined signal 1
SIGUSR2 31,12,17 Term User-defined signal 2
SIGCHLD 20,17,18 Ign Child stopped or terminated
SIGCONT 19,18,25 Cont Continue if stopped
SIGSTOP 17,19,23 Stop Stop process
SIGTSTP 18,20,24 Stop Stop typed at terminal
SIGTTIN 21,21,26 Stop Terminal input for background process
SIGTTOU 22,22,27 Stop Terminal output for background process
On UNIX systems the normal way to force terminate an app process is with
kill -9 PROCESS_ID
This sends the app the signal number nine which means: "you quit, NOW"
Generally unhandled exceptions will also cause the OS to terminate apps with this signal. Also killing an app via the "task switcher" does the same thing.
I know the original question was asking what does signal 9 mean, but I found this while looking for how to prevent it.
For me this was caused by sending a Local Notification and not implementing
application:didReceiveLocalNotification
in my AppDelegate. Once I did this, even with the method empty the crash did not reappear. Chances are there is something being called by the system that is not being handled by your code.
in linux there are around 64 signals (more than 64 in some system) ..if you want to see all signals numbering just type "kill -l" without quote on the terminal you will see all the list of signal these. signals are generated by the kernel or by kill system call by user on the particular application(e.g. kill -n app_name ). signal 9 is SIGKILL this is use to kill the application. though we can also mask some of the signals but not all signals can be masked in an application. for future ref. u can go here
http://en.wikipedia.org/wiki/Unix_signal
and also see the man page of signal you will get to know more
I was getting this from docker container, the reason came out to be low memory for docker while building the project. Make sure you have enough memory or memory is not leaking anywhere.

Resources