-
Notifications
You must be signed in to change notification settings - Fork 1
/
pierl_demo.erl
94 lines (85 loc) · 2.62 KB
/
pierl_demo.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
-module(pierl_demo).
-include("pierl.hrl").
-compile(export_all).
-define(PI, pierl).
forwarder(OwnChan) ->
?PI:recv(OwnChan, fun ({AckChan, OutputChan}) ->
?PI:send(AckChan, ack),
forwarder(OwnChan, OutputChan)
end).
forwarder(OwnChan, OutputChan) ->
?PI:recv(OwnChan, fun
%% also forward delegations
(?DELEGATION(Chan)) ->
?PI:delegate(Chan, OutputChan);
(M) ->
?PI:send(OutputChan, M)
end),
forwarder(OwnChan, OutputChan).
sender(OwnChan, PrinterChan) ->
random:seed(now()),
?PI:recv(OwnChan, fun (?DELEGATION(AckChan)) ->
?PI:recv(AckChan, fun (ack) ->
%% got ack, we can go!
ErrorChan = ?PI:new_chan(),
?PI:delegate(ErrorChan, PrinterChan),
sender_body(PrinterChan, ErrorChan, 2)
end
)
end).
sender_body(TargetChan, _, 0) ->
?PI:send(TargetChan,
"Ok, I am done with you."
);
sender_body(TargetChan, ErrorChan, Count) ->
case random:uniform(3) of
1 ->
?PI:send(TargetChan,
"You will get this message " ++
integer_to_list(Count - 1) ++
" more times."
),
sender_body(TargetChan, ErrorChan, Count - 1);
_ ->
?PI:send(ErrorChan,
"I failed to send you new messages, Printer."
),
sender_body(TargetChan, ErrorChan, Count)
end.
printer(OwnChan) ->
?PI:recv(OwnChan,
fun (?DELEGATION(ErrorChan)) ->
printer(OwnChan, ErrorChan)
end
).
printer(PrintChan, ErrorChan) ->
?PI:recv([
{PrintChan, fun (M) ->
io:format(user,
"Printer: oh hey, I got some message for printing: ~200p~n",
[M]
)
end},
{ErrorChan, fun (Err) ->
io:format(user,
"Printer: aahh! Something bad happened, err: ~200p~n",
[Err]
)
end}
]),
printer(PrintChan, ErrorChan).
start() ->
?PI:spawn(fun main/1).
main(_) ->
random:seed(now()),
PrinterChan = ?PI:spawn(fun printer/1),
ForwarderChan = ?PI:spawn(fun forwarder/1),
AckChan = ?PI:new_chan(),
?PI:send(ForwarderChan, {AckChan, PrinterChan}),
SenderChan = ?PI:spawn(
fun (SelfChan) -> sender(SelfChan, ForwarderChan) end),
%% This so that sometimes the ack would end up in this process
%% and sometimes it would get delayed and already arrive after the
%% delegation.
timer:sleep(random:uniform(12)),
?PI:delegate(AckChan, SenderChan).