Wake a process from sleeping - Erlang - 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.

Related

What happens when link and monitor the same process in 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.

Erlang process sending message

I understand that Erlang process message is sync.
When I do
Pid ! message
the sending message thread return right now
the sending message thread will confirm the message has put in the Pid's message queue and then return.
Which choice will the sending message thread do ?
I believe your understanding might be wrong. Erlang message passing is asynchronous.
For example have a look here.
To answer your question then the option number 1 is what's happening here.
In Erlang, message passing is asynchronous. The sender never blocks. Message delivery is not guaranteed. Caveats:
If messaging a local process, then in practice, messages always arrive and do so very quickly.
If messaging a remote process, then messages will be queued for sending. But due to the nature of TCP and distribution, it is not guaranteed that the message will be transferred and processed by the other party.
I think
the sending message thread return right now.
is right.
because Pid ! message just put the message into the message queue of process Pid. the process Pid will use receive to check its message queue. this is nothing with the sending process.

iOS. Measure time in setKeepAliveTimeout:handler: while waiting for server response

I am developing a VoIP app. When my app is in background I need to check if the server is still there. So I am trying to use setKeepAliveTimeout:handler: to make polls to server while app is in background.
The question is: how to ensure that I receive response or timeout within 5 seconds after I have sent poll message to server? If I don't receive response/timeout within 5 seconds the next opportunity to know that server is dead is only after keepAliveTimeout time which is not that good.
As I understand I can't setup NSTimer in setKeepAliveTimeout:handler: since we are in background (and NSTimer relies on run loop).
I see other possibility which is: make while loop and check for the current time in it. Although I would like to avoid making busy loops.
Could you please suggest me how can I achieve needed behaviour?

Broadcasting message to all connected users using websocket (Erlang, RabbitMQ, Websocket, Gen_bunny, Cowboy)

I am trying to integrate websocket chat using ERlang, Cowboy, Websocket and gen_bunny.
I am able to get them work independently.
Browser -> Cowboy websocket chat (Works)
Erlang and RabbitMQ AMQP (Works)
When integrating them together i am able to get the message from browser to Cowboy and pass it to RabbitMQ and again get it back from RabbitMQ.
I can even reply the message to the user who sent it. However, I want to broadcast the message to all connected Users.
As per my understanding Erlang will create a separate process for each user. So, how to broadcast it to all connected users after I get back the response from RabbitMQ??
Correct--Cowboy creates a per-connection process that runs your WebSocket handler code. One approach is to have the handler's websocket_init/3 function register itself with a "broadcast" process (and unregister in websocket_terminate/3). Upon receiving a message from RabbitMQ, the broadcast process repeats the message to all registered WebSocket connections, which can receive it using the websocket_info/3 handler callback.
The broadcast process can use monitors to discover when a WebSocket handler dies, and automatically remove it from the registration list.
The life of a handler, then, might look something like this:
websocket_init/3 is called after Cowboy performs the protocol upgrade requested in init/3 (to WebSocket). From here, the client handler registers itself with broadcast, the message broadcasting process.
As long as the connection remains open, the handler receives message broadcasts to its websocket_info/3, passing messages along to the client by returning {reply, {text, Message}, State}.
Upon termination, the handler unregisters itself with broadcast. If for some reason this doesn't work as intended, broadcast keeps monitors on all subscribers so as to get notified of their deaths.
Take a look on gproc project: https://github.com/uwiger/gproc
It has a Pub/Sub pattern that you may use to build the chat you mentioned.
From gproc's wiki:
subscribe(EventType) ->
%% Gproc notation: {p, l, Name} means {(p)roperty, (l)ocal, Name}
gproc:reg({p, l, {?MODULE, EventType}}).
notify(EventType, Msg) ->
Key = {?MODULE, EventType},
gproc:send({p, l, Key}, {self(), Key, Msg}).
Every cowboy process get its own Rabbit queue. Broadcast would work with wildcard bindings. No explicit loop involved. You could make the subscription optional by not binding accordingly. See: How to setup queue such a way all subscribers get messages - Rabbit MQ

PushSharp Push doesn't process queue until stop

PushSharp only processes the queue when stop is called. Does anyone have an idea how often push sharp will process the queue or flush it? I don't want to have to call stop and start every time I want to send a notification to conserve resources.
pushService = new PushService();
pushService.StartApplePushService(new ApplePushChannelSettings(prod, cert.InputStream.ReadToEnd(), passConfig.Value));
pushService.QueueNotification(
NotificationFactory.Apple().ForDeviceToken("mydeviceid").WithAlert("Notifications Started!").WithSound("default").WithBadge(7));
pushService.StopAllServices(true);
I'm a complete and utter idiot...
The main thread was completing execution before the queue timer could process the notification. StopAllServices forced the thread to wait... Maybe this will help someone else.

Resources