Delay won't work - process

I'm making an event calender as a task for school and I'm new to this.
The problem is that when I do a delay in the receive part of my loop, my table vanishes.
I'm looking on the internet and in my code for errors for 2 days now.
Event is a tuple => {{Time (tuple like now(), make_ref()}, NotifyPid, Load}
getTime gives back an integer normally
-module(calender).
-export([start/0, start_new/0, post/1, postincr/1, gettime/0]).
-export ([kalender/0, getTime/1, increment/1, makeTime/1]). % internal use only
%% #doc Starts the program
start() ->
case whereis('event manager') =:= undefined of
true ->
register('event manager', spawn(calender, kalender, [])),
{ok, 'event manager'};
false ->
{event_not_made}
end.
%% #doc Starts a new program even program already exist but kills it first
start_new() ->
case whereis('event manager') =:= undefined orelse unregister('event manager') of
true ->
ets:delete(calend),
register('event manager', spawn(calender, kalender, [])),
{ok, 'event manager'};
false ->
{ok, event_not_made}
end.
% Puts Events into sorted table
% Time is an integer value in milliseconds
post(Event) ->
'event manager'!{post, Event},
{ok, gettime()}.
%% #doc Puts Events into sorted table
%% Increment is an integer value which will be added to the present time
%% The increment value of time is in milliseconds
%% #end
postincr(Event) ->
'event manager'!{postincr, Event},
{ok, gettime()}.
%% #doc Gives the difference in time between present and time at start
gettime() ->
'event manager'!{gettime, self()},
receive
T -> T
end.
%% #private Calculates the difference of time between the present time and Event time
getTime(Time) ->
NowTime = now(),
timer:now_diff(Time, NowTime)div 1000.
%% #private Adds the incremental time of postincr to the present time
increment(Incr) ->
{X, Y, Z} = now(),
X1 = X * 1000000000000,
Y1 = Y * 1000000,
Incr1 = X1 + Y1 + Z + (Incr * 1000),
makeTime(Incr1).
%% #private Changes integer to tuple of 3 values
makeTime(Time) ->
X = Time div 1000000000000,
Y = (Time rem 1000000000000) div 1000000,
Z = Time rem 1000000,
{X, Y, Z}.
%% #private Makes the sorted table, starts the loop
kalender() ->
Cal = {ets:new(calend, [ordered_set, named_table, {keypos, 1}, public]), now()},
loop(Cal).
%% #private Loops through the table and checks for received messages
loop(Cal) ->
io:format("Loop start ~n"),
{Calen, TimeAtStart} = Cal,
io:format("Before case ~n"),
case ets:first(Calen) of
'$end_of_table' ->
io:format("end of table ~n"),
{end_of_table};
{Time, Ref} ->
io:format("Before calculation event ~n"),
Ms = getTime(Time),
io:format("After getTime ~n"),
if
Ms =< 0 ->
io:format("Ms =< 0 ~n"),
[Event | _Rest] = ets:lookup(Calen, {Time, Ref}),
io:format("~p~n", [Event]),
{{_Time1, _Ref1}, NotifyPid, _Load} = Event,
io:format("~p~n", [NotifyPid]),
NotifyPid!Event,
io:format("After event send ~n"),
ets:delete(Calen, {Time, Ref}),
io:format("After Ms =< 0 ~n");
Ms > 0 ->
io:format("Event not done ~n"),
{event_not_yet_done}
end,
io:format("After calculation event ~n")
end,
I think that it goes wrong from here somewhere:
io:format("Before Delay ~n"),
% Gets the delay time
Delay = case ets:first(Calen) of
'$end_of_table' ->
io:format("Delay infinity ~n"),
infinity;
{DelayTime, _DelayRef} ->
io:format("~p~n", [DelayTime]), => the DelayTime has for example a value of {9283,823031,155000}
Dl = getTime(DelayTime),
case Dl > 0 of
true ->
Dl,
io:format("~p~n", [Dl]); => this io:format gives me on the screen a calculated value example: 7899995274337
false ->
0,
io:format("0 ~n")
end,
io:format("Delay time~n")
end,
io:format("Before receive ~n"),
receive
{post, PostEvent} ->
io:format("In post ~n"),
{PostTimeI, Np, Ld} = PostEvent,
PostRef = make_ref(),
PostTimeT = makeTime((PostTimeI * 1000)),
io:format("After making the tuples ~n"),
io:format("~p ~p ~p ~p ~p~n", [PostTimeI, PostRef, PostTimeT, Np, Ld]),
ets:insert(Calen, {{PostTimeT, PostRef}, Np, Ld}),
io:format("After insert post ~p~n", [whereis('event manager')]);
{postincr, PostIncrEvent} ->
{Incr, Np, Ld} = PostIncrEvent,
PostIncrRef = make_ref(),
PostIncrTime = increment(Incr),
ets:insert(Calen, {{PostIncrTime, PostIncrRef}, Np, Ld});
{gettime, From} ->
From!getTime(TimeAtStart)
after
Delay ->
io:format("Delaying ~n"),
{ok}
end,
io:format("After receive ~n"),
loop(Cal).

The problem is probably that your process spawned with your start/0 function crashes. When a process crashes, any ETS tables it owns are reaped. Try using spawn_monitor and then use the shell's flush() command to get hold of messages that comes in. It probably dies. Another way is to use the tooling in the proc_lib module and then use erl -boot start_sasl to get some rudimentary crash error reporting up and running for your process.
A "naked" spawn(...) is usually dangerous since if the spawned process crashes, you won't learn anything. At least use spawn_link or spawn_monitor.

I found my problem:
I was testing my code but I didn't had a Pid to test with, so I used whereis('event manager'). Instead I had to use self().

Related

How can I get return value from a spawned process in Erlang?

I have the following code:
-module(a).
-compile(export_all).
say(2,0) ->
[1,2];
say(A,B) ->
say(A-1,B-1).
loop(0) ->
io:format("");
loop(Times) ->
L = spawn(a, say, [4,2]),
io:fwrite( "L is ~w ~n", [L] ),
loop(Times-1).
run() ->
loop(4).
I want to have the list [1,2] in L each time function 'say' completes. However, since the pid of the process is returned instead of the list from the function say due to use of spawn, I am getting the following output:
L is <0.113.0>
L is <0.114.0>
L is <0.115.0>
L is <0.116.0>
What I desire is
L is [1,2]
L is [1,2]
L is [1,2]
L is [1,2]
How can I achieve this?
To pass information between processes, you use ! to send a message to another process's mailbox, and you use a receive clause to extract a message from a process mailbox. Here is an example:
-module(a).
-compile(export_all).
%% Worker process:
say(From, 2, 0) ->
From ! {self(), [1,2]};
say(From, A, B) ->
say(From, A-1, B-1).
%% Main process:
loop(0) ->
ok;
loop(Times) ->
Pid = spawn(a, say, [self(), 4, 2]),
receive %%waits here for result before spawning another process--no concurrency
{Pid, Result} ->
io:fwrite( "L is ~w ~n", [Result] )
end,
loop(Times-1).
%% Test:
run() ->
loop(4).
In the shell:
7> c(a).
a.erl:2: Warning: export_all flag enabled - all functions will be exported
{ok,a}
8> a:run().
L is [1,2]
L is [1,2]
L is [1,2]
L is [1,2]
ok
9>
Or, you can spawn all the processes, then read the results as they come in:
-module(a).
-compile(export_all).
%% Worker process:
say(From, 2, 0) ->
From ! [1,2];
say(From, A, B) ->
say(From, A-1, B-1).
%% Main process:
loop(N) ->
loop(N, N).
loop(0, Times) ->
display_results(Times);
loop(N, Times) ->
spawn(a, say, [self(), 4, 2]),
loop(N-1, Times).
display_results(0) ->
ok;
display_results(Times) ->
receive
Result ->
io:format("L is ~w~n", [Result])
end,
display_results(Times-1).
%% Test:
run() ->
loop(4).
To ensure that you only receive messages from the processes that you spawned, you can do this:
-module(a).
-compile(export_all).
%% Worker process:
say(From, 2, 0) ->
From ! {self(), [1,2]};
say(From, A, B) ->
say(From, A-1, B-1).
%% Main process:
loop(Times) ->
loop(Times, _Pids=[]).
loop(0, Pids) ->
display_results(Pids);
loop(Times, Pids) ->
Pid = spawn(a, say, [self(), 4, 2]),
loop(Times-1, [Pid|Pids]).
display_results([]) ->
ok;
display_results([Pid|Pids]) ->
receive
{Pid, Result} ->
io:format("L is ~w~n", [Result])
end,
display_results(Pids).
%% Test:
run() ->
loop(4).
There are some risks when using a receive like that: if a worker process crashes before it sends the message to your main process, then your main process will be stuck indefinitely in the receive while waiting for a message to arrive from the crashed process. One solution: use a timeout in the receive. Another: use spawn_monitor().
You need to use messages (or signals) for that, as the code is running in a separate process.
I like to use spawn_monitor in that case:
1> {Pid, MonitorReference} = spawn_monitor(fun() -> timer:sleep(10000), exit({ok, [1,2]}) end),
1> receive {'DOWN', MonitorReference, process, Pid, {ok, Result}} -> Result end.
Keep in mind that you can receive for several messages at the same time or you can just receive them in order (leaving the out of order ones in the mailbox). So you can spawn several threads and wait for all of them to be finished, gathering the results:
work(Workload) ->
JobReference = make_ref(),
PidReferences = [spawn_monitor(fun() -> exit({JobReference, do_stuff(WorkSlice)}) end) || WorkSlice <- Workload],
[receive
{'DOWN', Reference, process, Pid, {JobReference, Result}} -> Result;
{'DOWN', Reference, process, Pid, Result} -> {error, Result}
end || {Pid, Reference} <- PidReferences].

Totality and searching for elements in Streams

I want a find function for Streams of size-bounded types which is analogous to the find functions for Lists and Vects.
total
find : MaxBound a => (a -> Bool) -> Stream a -> Maybe a
The challenge is it to make it:
be total
consume no more than constant log_2 N space where N is the number of bits required to encode the largest a.
take no longer than a minute to check at compile time
impose no runtime cost
Generally a total find implementation for Streams sounds absurd. Streams are infinite and a predicate of const False would make the search go on forever. A nice way to handle this general case is the infinite fuel technique.
data Fuel = Dry | More (Lazy Fuel)
partial
forever : Fuel
forever = More forever
total
find : Fuel -> (a -> Bool) -> Stream a -> Maybe a
find Dry _ _ = Nothing
find (More fuel) f (value :: xs) = if f value
then Just value
else find fuel f xs
That works well for my use case, but I wonder if in certain specialized cases the totality checker could be convinced without using forever. Otherwise, somebody may suffer a boring life waiting for find forever ?predicateWhichHappensToAlwaysReturnFalse (iterate S Z) to finish.
Consider the special case where a is Bits32.
find32 : (Bits32 -> Bool) -> Stream Bits32 -> Maybe Bits32
find32 f (value :: xs) = if f value then Just value else find32 f xs
Two problems: it's not total and it can't possibly return Nothing even though there's a finite number of Bits32 inhabitants to try. Maybe I could use take (pow 2 32) to build a List and then use List's find...uh, wait...the list alone would take up GBs of space.
In principle it doesn't seem like this should be difficult. There's finitely many inhabitants to try, and a modern computer can iterate through all 32-bit permutations in seconds. Is there a way to have the totality checker verify the (Stream Bits32) $ iterate (+1) 0 eventually cycles back to 0 and once it does assert that all the elements have been tried since (+1) is pure?
Here's a start, although I'm unsure how to fill the holes and specialize find enough to make it total. Maybe an interface would help?
total
IsCyclic : (init : a) -> (succ : a -> a) -> Type
data FinStream : Type -> Type where
MkFinStream : (init : a) ->
(succ : a -> a) ->
{prf : IsCyclic init succ} ->
FinStream a
partial
find : Eq a => (a -> Bool) -> FinStream a -> Maybe a
find pred (MkFinStream {prf} init succ) = if pred init
then Just init
else find' (succ init)
where
partial
find' : a -> Maybe a
find' x = if x == init
then Nothing
else
if pred x
then Just x
else find' (succ x)
total
all32bits : FinStream Bits32
all32bits = MkFinStream 0 (+1) {prf=?prf}
Is there a way to tell the totality checker to use infinite fuel verifying a search over a particular stream is total?
Let's define what it means for a sequence to be cyclic:
%default total
iter : (n : Nat) -> (a -> a) -> (a -> a)
iter Z f = id
iter (S k) f = f . iter k f
isCyclic : (init : a) -> (next : a -> a) -> Type
isCyclic init next = DPair (Nat, Nat) $ \(m, n) => (m `LT` n, iter m next init = iter n next init)
The above means that we have a situation which can be depicted as follows:
-- x0 -> x1 -> ... -> xm -> ... -> x(n-1) --
-- ^ |
-- |---------------------
where m is strictly less than n (but m can be equal to zero). n is some number of steps after which we get an element of the sequence we previously encountered.
data FinStream : Type -> Type where
MkFinStream : (init : a) ->
(next : a -> a) ->
{prf : isCyclic init next} ->
FinStream a
Next, let's define a helper function, which uses an upper bound called fuel to break out from the loop:
findLimited : (p : a -> Bool) -> (next : a -> a) -> (init : a) -> (fuel : Nat) -> Maybe a
findLimited p next x Z = Nothing
findLimited p next x (S k) = if p x then Just x
else findLimited pred next (next x) k
Now find can be defined like so:
find : (a -> Bool) -> FinStream a -> Maybe a
find p (MkFinStream init next {prf = ((_,n) ** _)}) =
findLimited p next init n
Here are some tests:
-- I don't have patience to wait until all32bits typechecks
all8bits : FinStream Bits8
all8bits = MkFinStream 0 (+1) {prf=((0, 256) ** (LTESucc LTEZero, Refl))}
exampleNothing : Maybe Bits8
exampleNothing = find (const False) all8bits -- Nothing
exampleChosenByFairDiceRoll : Maybe Bits8
exampleChosenByFairDiceRoll = find ((==) 4) all8bits -- Just 4
exampleLast : Maybe Bits8
exampleLast = find ((==) 255) all8bits -- Just 255

Promela - non-determinism not non-deterministic?

Consider this snippet:
chan sel = [0] of {int};
active proctype Selector(){
int not_me;
endselector:
do
:: sel ? not_me;
if
:: 0 != not_me -> sel ! 0;
:: 1 != not_me -> sel ! 1;
:: 2 != not_me -> sel ! 2;
:: 3 != not_me -> sel ! 3;
:: else -> -1;
fi
od
}
proctype H(){
int i = -1;
int count = 1000;
do
:: sel ! i; sel ? i; printf("currently selected: %d\n",i); count = count -1;
:: count < 0 -> break;
od
assert(false);
}
init{
atomic{
run H();
}
}
You'd expect this to print pretty the values 0..3 pretty arbitrarily until the counter falls below 0, at which point it can either print another number or it will terminate.
However, that doesn't seem to be the case.
The only values returned are 0, then 1, then 0, then 1, then 0, then 1, ...
Did I somehow misunderstand the "non-determinism" of the if/fi statements?
(using ispin on ubuntu, if that matters).
Relevant part of language spec. Seems non-determinstic to me.
If you're looking at (a few) traces of the system only, then you're at the mercy of the (pseudo) random generator.
I thought the main purpose of SPIN is to prove properties. So, you could write a formula F that describes the trace(s) that you want, and then have SPIN check that "system and F" has a model.
If you are running Spin in 'simulation' mode, then the else options are visited deterministically, I believe. So in the Selector proctype, the simulation proceeds in the if by checking the options as: 0 ~= not_me and then the 1, 2, 3 options. For your execution, you thus ping pong between 0 and 1.
You can confirm this, by replacing your if statement with:
if
:: 0 != not_me -> sel ! 0;
:: 1 != not_me -> sel ! 1;
:: else -> assert(false)
fi
and your simulation will never reach the assert.
Spin can also be run in 'verification' mode - generate a pan executable and execute that. Then, all cases will be visited (modulo limits in memory and time). However, in 'verification' mode nothing is printed out - so you might be hard pressed to see the other cases!

Erlang Dynamic Record Editing

I'm storing some data in mnesia, and I'd like to be able to change most of the values involved.
The naive
change(RecordId, Slot, NewValue) ->
[Rec] = do(qlc:q([X || X <- mnesia:table(rec), X#rec.id =:= RecordId])),
NewRec = Rec#rec{Slot=NewValue},
F = fun() -> mnesia:write(NewRec) end,
{atomic, Val} = mnesia:transaction(F),
Val.
doesn't do it; the compiler complains that Slot is not an atom or _. Is there a way to express a general slot editing function as above, or am I going to be stuck defining a whole bunch of change_slots?
A marginally better approach is to pull out the insert and find pieces
atomic_insert(Rec) ->
F = fun() -> mnesia:write(Rec) end,
{atomic, Val} = mnesia:transaction(F),
Val.
find(RecordId) ->
[Rec] = do(qlc:q([X || X <- mnesia:table(rec), X#rec.id =:= RecordId])),
Rec.
change(RecordId, name, NewValue) ->
Rec = find(RecordId),
NewRec = Rec#rec{name=NewValue},
atomic_insert(NewRec);
change(RecordId, some_other_property, NewValue) ->
Rec = find(RecordId),
NewRec = Rec#rec{some_other_property=NewValue},
...
but there's still a bit of code duplication there. Is there any way to abstract that pattern out? Is there an established technique to allow records to be edited? Any ideas in general?
Since records are represented by tuples, you could try using tuple operations to set individual values.
-module(rec).
-export([field_num/1, make_rec/0, set_field/3]).
-record(rec, {slot1, slot2, slot3}).
make_rec() ->
#rec{slot1=1, slot2=2, slot3=3}.
field_num(Field) ->
Fields = record_info(fields, rec),
DifField = fun (FieldName) -> Field /= FieldName end,
case length(lists:takewhile(DifField, Fields)) of
Length when Length =:= length(Fields) ->
{error, not_found};
Length ->
Length + 2
end.
set_field(Field, Value, Record) ->
setelement(field_num(Field), Record, Value).
set_field will return an updated record:
Eshell V5.9.1 (abort with ^G)
1> c(rec).
{ok,rec}
2> A = rec:make_rec().
{rec,1,2,3}
3> B = rec:set_field(slot3, other_value, A).
{rec,1,2,other_value}
You can also define change as a macro (especially if it used only inside the module):
-define(change(RecordId, Slot, NewValue),
begin
[Rec] = do(qlc:q([X || X <- mnesia:table(rec), X#rec.id =:= RecordId])),
NewRec = Rec#rec{Slot=NewValue},
F = fun() -> mnesia:write(NewRec) end,
{atomic, Val} = mnesia:transaction(F),
Val
end).
Usage:
test(R, Id) ->
?change(Id, name, 5).
With macro you can also pass _ as a field (good for pattern matching).
Another way of using that a record is really a tuple would be:
change(RecordId, Index, NewValue) ->
[Rec] = do(qlc:q([X || X <- mnesia:table(rec), X#rec.id =:= RecordId])),
NewRec = setelement(Index, Rec, NewValue),
F = fun() -> mnesia:write(NewRec) end,
{atomic, Val} = mnesia:transaction(F),
Val.
which you could use like this:
5> Val = record:change(id58, #rec.name, new_value).
This is also a "clean" use of records as tuples as you are using the #rec.name syntax to find the index of the field in the tuple. It was the reason this syntax was added.

How to receive message from 'any' channel in PROMELA/SPIN

I'm modeling an algorithm in Spin.
I have a process that has several channels and at some point, I know a message is going to come but don't know from which channel. So want to wait (block) the process until it a message comes from any of the channels. how can I do that?
I think you need Promela's if construct (see http://spinroot.com/spin/Man/if.html).
In the process you're referring to, you probably need the following:
byte var;
if
:: ch1?var -> skip
:: ch2?var -> skip
:: ch3?var -> skip
fi
If none of the channels have anything on them, then "the selection construct as a whole blocks" (quoting the manual), which is exactly the behaviour you want.
To quote the relevant part of the manual more fully:
"An option [each of the :: lines] can be selected for execution only when its guard statement is executable [the guard statement is the part before the ->]. If more than one guard statement is executable, one of them will be selected non-deterministically. If none of the guards are executable, the selection construct as a whole blocks."
By the way, I haven't syntax checked or simulated the above in Spin. Hopefully it's right. I'm quite new to Promela and Spin myself.
If you want to have your number of channels variable without having to change the implementation of the send and receive parts, you might use the approach of the following producer-consumer example:
#define NUMCHAN 4
chan channels[NUMCHAN];
init {
chan ch1 = [1] of { byte };
chan ch2 = [1] of { byte };
chan ch3 = [1] of { byte };
chan ch4 = [1] of { byte };
channels[0] = ch1;
channels[1] = ch2;
channels[2] = ch3;
channels[3] = ch4;
// Add further channels above, in
// accordance with NUMCHAN
// First let the producer write
// something, then start the consumer
run producer();
atomic { _nr_pr == 1 ->
run consumer();
}
}
proctype consumer() {
byte var, i;
chan theChan;
i = 0;
do
:: i == NUMCHAN -> break
:: else ->
theChan = channels[i];
if
:: skip // non-deterministic skip
:: nempty(theChan) ->
theChan ? var;
printf("Read value %d from channel %d\n", var, i+1)
fi;
i++
od
}
proctype producer() {
byte var, i;
chan theChan;
i = 0;
do
:: i == NUMCHAN -> break
:: else ->
theChan = channels[i];
if
:: skip;
:: theChan ! 1;
printf("Write value 1 to channel %d\n", i+1)
fi;
i++
od
}
The do loop in the consumer process non-deterministically chooses an index between 0 and NUMCHAN-1 and reads from the respective channel, if there is something to read, else this channel is always skipped. Naturally, during a simulation with Spin the probability to read from channel NUMCHAN is much smaller than that of channel 0, but this does not make any difference in model checking, where any possible path is explored.