eunit test for timeout - unit-testing

How can I test that a gen_fsm does indeed timeout with eunit?
{ok, GH} = gen_fsm:start_link(myFSM, [], []),
//after 15 sec it should timeout if no messages received.
//What must I write here to test it?

I believe this is one solution:
{ok, GH} = gen_fsm:start_link(myFSM, [], []),
Ref = erlang:monitor(process,GH),
receive
{'DOWN', Ref, process, GH, normal} ->
test_passed
after
15000 ->
?assert("FSM did not die.") % will always fail
end.

Related

Concurrency in Erlang

The problem I am trying to solve is as follows:
Write an Erlang function named squared that takes no parameters. This function should wait to receive a message. The message will be in the format { Pid, N }, where you may assume that Pid is a process ID and N is a number. The function should send a message to the process ID Pid in the form { Me, X } where Me is the process ID of the process running the function and X is the value of N squared. The function should then end.
so far I have this:
-module(main).
-export([squared/0]).
squared() ->
receive
{Pid,N} -> Pid ! {Me, X}, squared();
terminate -> ok
end.
The error that I am getting is as follows:
3> c(main).
main.erl:7: variable 'Me' is unbound
main.erl:7: variable 'X' is unbound
main.erl:7: Warning: variable 'N' is unused
error
I am also having trouble in the second part of the problem where it is asking us to send a message to the process ID in the form {Me, X}. Where Me is the process ID and X is the value of N squared. How will we do that?
for implement your function you can write a function like bellow
-module(main).
-export([squared/0]).
squared() ->
receive
{Pid,N} ->
Pid ! {self(), N*N},
squared();
terminate ->
ok
end.
Me should be the pid of the receiving process, i.e. self(). N squared is just N*N.
-module(main).
-export([squared/0]).
squared() ->
receive
{Pid, N} ->
Pid ! {self(), N*N};
terminate -> ok
end.
Or, if you want to be more verbous:
squared() ->
Me = self(),
receive
{Pid, N} ->
X = N * N,
Pid ! {Me, X};
terminate -> ok
end.

Erlang: Trying to generate sets of monitors that only monitor 10 child processes

So the idea is that we need to take in a number of child processes to spawn/monitor, but we need to spin up monitor processes such that they only deal with less than 10 child processes at a time. So if we take in 35 child processes, we'd need to have 4 monitors, 3 that monitor 10 children, and one that monitors 5.
The problem is that I'm struggling to figure out why the code I've written for this purpose fails. Here's the code:
-module(watcher).
-import(sensor, [start/0]).
-export([start/1, stop/0]).
start(NrSlaves) ->
MasterPids = [],
MasterPid = spawn(fun() -> master_starter(NrSlaves, MasterPids) end),
register(master, MasterPid),
ok.
stop() ->
master ! die,
ok.
slave_pid_to_nr(SlavePid, SlavePids) ->
slave_pid_to_nr(SlavePid, SlavePids, 1).
slave_pid_to_nr(SlavePid, [SlavePid | _Tail], SlaveNr) ->
SlaveNr;
slave_pid_to_nr(SlavePid, [_Head | Tail], SlaveNr) ->
slave_pid_to_nr(SlavePid, Tail, SlaveNr + 1).
slave_change_pid(OldSlavePid, NewSlavePid, SlavePids) ->
lists:map(
fun(Pid) ->
if
Pid == OldSlavePid ->
NewSlavePid;
true ->
Pid
end
end,
SlavePids
).
%This is the part that errors out
master_starter(NrSlaves, MasterPids) ->
if (NrSlaves/10) =< 1 ->
MasterPids = MasterPids ++ [spawn_link(fun() -> master_start(NrSlaves) end)];
true->
MasterPids = MasterPids ++ [spawn_link(fun() -> master_start(10) end) || lists:seq(1, (NrSlaves/10))],
master_starter(NrSlaves-10, MasterPids)
end,
receive
die ->
io:fwrite("Monitor: received die~n"),
lists:foreach(fun(MasterPid) -> MasterPid ! die end, MasterPids)
end.
master_start(NrSlaves) ->
process_flag(trap_exit, true),
io:fwrite("monitor: started~n", []),
SlavePids = [spawn_link(fun() -> slave_start(SlaveNr) end) || SlaveNr <- lists:seq(1, NrSlaves)],
master_loop(SlavePids).
master_loop(SlavePids) ->
receive
die ->
io:fwrite("Monitor: received die~n"),
lists:foreach(fun(SlavePid) -> SlavePid ! die end, SlavePids);
{SlaveNr, Measurement} ->
io:fwrite("Sensor# ~p measures ~p~n", [SlaveNr, Measurement]),
master_loop(SlavePids);
{'EXIT', SlavePid, _Reason} ->
SlaveNr = slave_pid_to_nr(SlavePid, SlavePids),
io:fwrite("Monitor: Sensor ~p with PID ~p died because of a crash~n", [SlaveNr, SlavePid]),
NewSlavePid = spawn_link(fun() -> slave_start(SlaveNr) end),
NewSlavePids = slave_change_pid(SlavePid, NewSlavePid, SlavePids),
master_loop(NewSlavePids)
end.
slave_start(SlaveNr) ->
% SlavePid = lists:nth(SlaveNr, SlavePids),
io:fwrite("sensor ~p with PID ~p: started~n", [SlaveNr, self()]),
%%slave_loop(SlaveNr).
sensor:start(SlaveNr).
I'm getting errors like: "Error in process <0.573.0> with exit value: {{badmatch,[<0.574.0>]},[{watcher,master_starter,2,[{file,"watcher.erl"},{line,39}]}]}"
Any help would be appreciated. It's very close to being finished, but I just need to understand why this isn't working.
There are three problems I see in your code.
Variables are immutable, and MasterPids = MasterPids ++ ... will fail with badmatch error. Try assigning to new variable like NewPids or MasterPids2.
You are missing generator in you list comprehension. You should have <- somewhere there, like [spawn_link( ... ) || _ <- lists:seq(1, (NrSlaves/10)).
lists:seq do not takes floats. You have to round up NrSlaves/10 to integer. You could use ceiling function from here (maybe simplify a little, since you won't use negative numbers).
Variable are not mutable in erlang. so
MasterPids = MasterPids ++ [spawn_link(fun() -> master_start(NrSlaves) end)];
will fail since you try to modify MasterPids

How do I restart an erlang process in a list?

I have a list construction like this:
[{Value, spawn_link(fun() -> worker(Value, self()) end)} || Value <- List]
So I have a list with values and each value is handed in its own process with the line above. If one worker dies, I want to restart it (with the same value). I have saved the Value in the same tupel as the new process as above. Can I do some list comprehension to determine if the process has died, and in that case, start a new?
Use erlang:monitor/2 to watch for your processes:
List1 = [{Value, spawn_link(fun() -> worker(Value, self()) end)} || Value <- List],
List2 = [{Value, Pid, monitor(process, Pid)} || {Value, Pid} <- List1]
And then wait for messages for monitors, restart your processes if you need and update List2 with new pids and monitors.
To get more info about erlang:monitor/2 read appropriate man page.
In your home made supervisor, don't forget to set process_flag(trap_exit, true) otherwise it will die at the same time one child die, and then all other children too:
1> F = fun() -> timer:sleep(2000) end.
#Fun<erl_eval.20.80484245>
2> F1 = fun() -> timer:sleep(2000), 1/0 end.
#Fun<erl_eval.20.80484245>
3> S = fun() -> spawn_link(F), receive M-> M after 5000 -> no_message end end.
#Fun<erl_eval.20.80484245>
4> S1 = fun() -> spawn_link(F1), receive M-> M after 5000 -> no_message end end.
#Fun<erl_eval.20.80484245>
5> S1b = fun() -> process_flag(trap_exit, true), spawn_link(F1), receive M-> M after 5000 -> no_message end end.
#Fun<erl_eval.20.80484245>
6> self().
<0.40.0>
7> S().
no_message
8> self().
<0.40.0>
9> S1().
=ERROR REPORT==== 15-Mar-2014::06:46:27 ===
Error in process <0.49.0> with exit value: {badarith,[{erlang,'/',[1,0],[]}]}
** exception exit: badarith
in operator '/'/2
called as 1 / 0
10> self().
<0.50.0>
11> S1b().
=ERROR REPORT==== 15-Mar-2014::06:46:39 ===
Error in process <0.53.0> with exit value: {badarith,[{erlang,'/',[1,0],[]}]}
{'EXIT',<0.53.0>,{badarith,[{erlang,'/',[1,0],[]}]}}
12> self().
<0.50.0>
13>
Unless you are doing this for education purpose, I recommend you to use the erlang otp supervisors, with a one_for_one restart strategy.
First, create a function that creates a process that monitors a Pid and executes a Fun when it dies, like so:
on_exit(Pid, Fun) ->
spawn(fun() ->
Ref = monitor(process, Pid),
receive
{'DOWN', Ref, process, Pid, Why} ->
Fun(Why)
end
end).
Now, you can use the on_exit function to create a function for creating processeses that will restart automatically when the process dies:
keep_alive(Fun) ->
process_flag(trap_exit, true),
Pid = spawn_link(Fun),
on_exit(Pid, fun(Why) ->
io:format("Process died: ~p, restarting it~n", [Why]),
keep_alive(Fun) end),
Pid.
With these little two functions, your work to create processes that will restart automatically is reduced to simply calling keep_alive in your list comprehension:
[{Value, keep_alive(fun() -> worker(Value, self()) end)} || Value <- List].
P.S.: These two little functions are presented almost exactly like this in chapter 13 of the book Programming Erlang 2nd Edition, I only did some minor changes to better suit to your case.

Sending messages in circles.

I am new to functional programming and just switched from haskell (Didn't like it much) to erlang (quite fond of it). As I am learning as an autodidact, I stumbled over these Exercises and started doing them.
I came as far as this problem:
Write a function which starts 2 processes, and sends a message M
times forewards and backwards between them. After the messages have
been sent the processes should terminate gracefully.
I resolved it like this and it works (maybe it can be done better; any comment highly appreciated):
-module (concur).
-export ( [pingpong/1, pingpong/2] ).
pingpong (Msg, TTL) ->
A = spawn (concur, pingpong, ["Alice"] ),
B = spawn (concur, pingpong, ["Bob"] ),
B ! {A, TTL * 2, Msg}.
pingpong (Name) ->
receive
{From, 1, Msg} ->
io:format ("~s received ~p and dying.~n", [Name, Msg] ),
exit (From);
{From, TTL, Msg} ->
io:format ("~s received ~p.~n", [Name, Msg] ),
From ! {self (), TTL - 1, Msg},
pingpong (Name)
end.
The real problem is the next exercise:
2) Write a function which starts N processes in a ring, and sends a
message M times around all the processes in the ring. After the
messages have been sent the processes should terminate gracefully.
As I am not sending the message back to its originator, but to the next node in the chain, I somehow have to pass to the sending process the process of the recipient. So I imagined that the function would look something like this:
pingCircle (Name, Next) ->
...
receive {TTL, Msg} -> Next ! {TTL - 1, Msg}
...
But how do I start this whole thing. When I spawn the first function in the circle, I still haven't spawned the next node and hence I cannot pass it as an argument. So my naive approach doesn't work:
First = spawn (concur, pingCirle, ["Alice", Second] ),
Second = spawn (concur, pingCirle, ["Bob", Third] ),
...
Also the approach of passing the spawn call of the next node recursively as a parameter to it predecessor, doesn't solve the problem how to close the circle, i.e. passing the last node to the first.
The question is:
How can I build this circle?
EDIT:
Thanks to your great answers, I managed to what I intended. Hence this question is solved.
One possible solution is:
-module (concur).
-export ( [pingCircle/3, pingCircle/2] ).
pingCircle (Names, Message, TTL) ->
Processes = lists:map (fun (Name) -> spawn (?MODULE, pingCircle, [Name, nobody] ) end, Names),
ProcessPairs = lists:zip (Processes, rot1 (Processes) ),
lists:map (fun ( {Process, Recipient} ) -> Process ! {setRecipient, Recipient} end, ProcessPairs),
Circle = lists:map (fun ( {Process, _} ) -> Process end, ProcessPairs),
hd (Circle) ! {Message, TTL - 1, lists:last (Circle) }.
rot1 ( [] ) -> [];
rot1 ( [Head | Tail] ) -> Tail ++ [Head].
pingCircle (Name, Recipient) ->
receive
{setRecipient, NewRecipient} ->
pingCircle (Name, NewRecipient);
{Message, 0, Originator} ->
io:format ("~s received ~p with TTL 0 and dying.~n", [Name, Message] ),
if
Originator == self () -> io:format ("All dead.~n");
true -> Recipient ! {Message, 0, Originator}
end;
{Message, TTL, Originator} ->
io:format ("~s received ~p with TTL ~p.~n", [Name, Message, TTL] ),
if
Originator == self () -> Recipient ! {Message, TTL - 1, Originator};
true -> Recipient ! {Message, TTL, Originator}
end,
pingCircle (Name, Recipient)
end.
Here is my peer review link.
This exercise has become a rite of passage for all erlang programmers. I gave a working solution to it here, along with an explanation that may be helpful.
Spawn them first, then send them a start signal.
The start signal would be sent after all the processes are already running.
Someone already came up with the answer here -> http://simplehappy.iteye.com/?show_full=true
My answer.
-module(con_test).
start_ring(Msg, M, N) ->
[First|_]=Processes=[spawn(?MODULE, ring, []) || _ <- lists:seq(1,N)],
First ! {rotLeft(Processes), {Msg, M*N}}.
ring() ->
receive
{_List, {Msg, Count}} when Count == 0 ->
io:format("~p got ~s. Enough! I'm out.~n", [self(), Msg]),
exit(normal);
{[Next|_] = List, {Msg, Count}} when Count > 0 ->
io:format("~p got ~s. Passing it forward to ~p.~n", [self(), Msg, Next]),
Next ! {rotLeft(List), {Msg, Count-1}},
ring()
after 1000 ->
io:format("~p is out.~n", [self()]),
exit(normal)
end.
rotLeft([]) -> [];
rotLeft([H|T]) -> T ++[H].

How to use TryScan in F# properly

I was trying to find an example about how to use TryScan, but haven't found any, could you help me?
What I would like to do (quite simplified example): I have a MailboxProcessor that accepts
two types of mesages.
First one GetState returns current state.
GetState messages are sent quite frequently
The other UpdateState is very expensive (time consuming) - e.g. downloading something from internet and then updates the state accordingly.
UpdateState is called only rarely.
My problem is - messages GetState are blocked and wait until preceding UpdateState are served. That's why I tried to use TryScan to process all GetState messages, but with no luck.
My example code:
type Msg = GetState of AsyncReplyChannel<int> | UpdateState
let mbox = MailboxProcessor.Start(fun mbox ->
let rec loop state = async {
// this TryScan doesn't work as expected
// it should process GetState messages and then continue
mbox.TryScan(fun m ->
match m with
| GetState(chnl) ->
printfn "G processing TryScan"
chnl.Reply(state)
Some(async { return! loop state})
| _ -> None
) |> ignore
let! msg = mbox.Receive()
match msg with
| UpdateState ->
printfn "U processing"
// something very time consuming here...
async { do! Async.Sleep(1000) } |> Async.RunSynchronously
return! loop (state+1)
| GetState(chnl) ->
printfn "G processing"
chnl.Reply(state)
return! loop state
}
loop 0
)
[async { for i in 1..10 do
printfn " U"
mbox.Post(UpdateState)
async { do! Async.Sleep(200) } |> Async.RunSynchronously
};
async { // wait some time so that several `UpdateState` messages are fired
async { do! Async.Sleep(500) } |> Async.RunSynchronously
for i in 1..20 do
printfn "G"
printfn "%d" (mbox.PostAndReply(GetState))
}] |> Async.Parallel |> Async.RunSynchronously
If you try to run the code, you will see, that GetState message is not almost processed, because it waits for the result. On the other hand UpdateState is only fire-and-forget, thus blocking effectively getting state.
Edit
Current solution that works for me is this one:
type Msg = GetState of AsyncReplyChannel<int> | UpdateState
let mbox = MailboxProcessor.Start(fun mbox ->
let rec loop state = async {
// this TryScan doesn't work as expected
// it should process GetState messages and then continue
let! res = mbox.TryScan((function
| GetState(chnl) -> Some(async {
chnl.Reply(state)
return state
})
| _ -> None
), 5)
match res with
| None ->
let! msg = mbox.Receive()
match msg with
| UpdateState ->
async { do! Async.Sleep(1000) } |> Async.RunSynchronously
return! loop (state+1)
| _ -> return! loop state
| Some n -> return! loop n
}
loop 0
)
Reactions to comments: the idea with other MailboxProcessor or ThreadPool that executes UpdateState in parallel is great, but I don't need it currently.
All I wanted to do is to process all GetState messages and after that the others. I don't care that during processing UpdateState the agent is blocked.
I'll show you what was the problem on the output:
// GetState messages are delayed 500 ms - see do! Async.Sleep(500)
// each UpdateState is sent after 200ms
// each GetState is sent immediatelly! (not real example, but illustrates the problem)
U 200ms <-- issue UpdateState
U processing <-- process UpdateState, it takes 1sec, so other
U 200ms 5 requests are sent; sent means, that it is
U 200ms fire-and-forget message - it doesn't wait for any result
and therefore it can send every 200ms one UpdateState message
G <-- first GetState sent, but waiting for reply - so all
previous UpdateState messages have to be processed! = 3 seconds
and AFTER all the UpdateState messages are processed, result
is returned and new GetState can be sent.
U 200ms
U 200ms because each UpdateState takes 1 second
U 200ms
U processing
U
U
U
U
U processing
G processing <-- now first GetState is processed! so late? uh..
U processing <-- takes 1sec
3
G
U processing <-- takes 1sec
U processing <-- takes 1sec
U processing <-- takes 1sec
U processing <-- takes 1sec
U processing <-- takes 1sec
U processing <-- takes 1sec
G processing <-- after MANY seconds, second GetState is processed!
10
G
G processing
// from this line, only GetState are issued and processed, because
// there is no UpdateState message in the queue, neither it is sent
I don't think that the TryScan method will help you in this scenario. It allows you to specify timeout to be used while waiting for messages. Once some message is received, it will start processing the message (ignoring the timeout).
For example, if you wanted to wait for some specific message, but perform some other checking every second (while waiting) you could write:
let loop () = async {
let! res = mbox.TryScan(function
| ImportantMessage -> Some(async {
// process message
return 0
})
| _ -> None)
match res with
| None ->
// perform some check & continue waiting
return! loop ()
| Some n ->
// ImportantMessage was received and processed
}
What can you do to avoid blocking the mailbox processor when processing the UpdateState message? The mailbox processor is (logically) single-threaded - you probably don't want to cancel the processing of UpdateState message, so the best option is to start processing it in background and wait until the processing completes. The code that processes UpdateState can then send some message back to the mailbox (e.g. UpdateStateCompleted).
Here is a sketch how this might look:
let rec loop (state) = async {
let! msg = mbox.Receive()
match msg with
| GetState(repl) ->
repl.Reply(state)
return! scanning state
| UpdateState ->
async {
// complex calculation (runs in parallel)
mbox.Post(UpdateStateCompleted newState) }
|> Async.Start
| UpdateStateCompleted newState ->
// Received new state from background workflow
return! loop newState }
Now that the background task is running in parallel, you need to be careful about mutable state. Also, if you send UpdateState messages faster than you can process them, you'll be in trouble. This can be fixed, for example, by ignoring or queueing requests when you're already processing previous one.
DON'T USE TRYSCAN!!!
Unfortunately, the TryScan function in the current version of F# is broken in two ways. Firstly, the whole point is to specify a timeout but the implementation does not actually honor it. Specifically, irrelevant messages reset the timer. Secondly, as with the other Scan function, the message queue is examined under a lock that prevents any other threads from posting for the duration of the scan, which can be an arbitrarily long time. Consequently, the TryScan function itself tends to lock-up concurrent systems and can even introduce deadlocks because the caller's code is evaluated inside the lock (e.g. posting from the function argument to Scan or TryScan can deadlock the agent when the code under the lock blocks waiting to acquire the lock it is already under).
I used TryScan in an early prototype of my production code and it caused no end of problems. However, I managed to architect around it and the resulting architecture was actually better. In essence, I eagerly Receive all messages and filter using my own local queue.
As Tomas mentioned MailboxProcessor is single threaded. You will need another MailboxProcessor to run the updates on a separate thread from the state getter.
#nowarn "40"
type Msg =
| GetState of AsyncReplyChannel<int>
| UpdateState
let runner_UpdateState = MailboxProcessor.Start(fun mbox ->
let rec loop = async {
let! state = mbox.Receive()
printfn "U start processing %d" !state
// something very time consuming here...
do! Async.Sleep 100
printfn "U done processing %d" !state
state := !state + 1
do! loop
}
loop
)
let mbox = MailboxProcessor.Start(fun mbox ->
// we need a mutiple state if another thread can change it at any time
let state = ref 0
let rec loop = async {
let! msg = mbox.Receive()
match msg with
| UpdateState -> runner_UpdateState.Post state
| GetState chnl -> chnl.Reply !state
return! loop
}
loop)
[
async {
for i in 1..10 do
mbox.Post UpdateState
do! Async.Sleep 200
};
async {
// wait some time so that several `UpdateState` messages are fired
do! Async.Sleep 1000
for i in 1..20 do
printfn "G %d" (mbox.PostAndReply GetState)
do! Async.Sleep 50
}
]
|> Async.Parallel
|> Async.RunSynchronously
|> ignore
System.Console.ReadLine() |> ignore
output:
U start processing 0
U done processing 0
U start processing 1
U done processing 1
U start processing 2
U done processing 2
U start processing 3
U done processing 3
U start processing 4
U done processing 4
G 5
U start processing 5
G 5
U done processing 5
G 5
G 6
U start processing 6
G 6
G 6
U done processing 6
G 7
U start processing 7
G 7
G 7
U done processing 7
G 8
G U start processing 8
8
G 8
U done processing 8
G 9
G 9
U start processing 9
G 9
U done processing 9
G 9
G 10
G 10
G 10
G 10
You could also use ThreadPool.
open System.Threading
type Msg =
| GetState of AsyncReplyChannel<int>
| SetState of int
| UpdateState
let mbox = MailboxProcessor.Start(fun mbox ->
let rec loop state = async {
let! msg = mbox.Receive()
match msg with
| UpdateState ->
ThreadPool.QueueUserWorkItem((fun obj ->
let state = obj :?> int
printfn "U start processing %d" state
Async.Sleep 100 |> Async.RunSynchronously
printfn "U done processing %d" state
mbox.Post(SetState(state + 1))
), state)
|> ignore
| GetState chnl ->
chnl.Reply state
| SetState newState ->
return! loop newState
return! loop state
}
loop 0)
[
async {
for i in 1..10 do
mbox.Post UpdateState
do! Async.Sleep 200
};
async {
// wait some time so that several `UpdateState` messages are fired
do! Async.Sleep 1000
for i in 1..20 do
printfn "G %d" (mbox.PostAndReply GetState)
do! Async.Sleep 50
}
]
|> Async.Parallel
|> Async.RunSynchronously
|> ignore
System.Console.ReadLine() |> ignore