Adding some erlang stuff.
This commit is contained in:
parent
4aae9be7cd
commit
71975c1070
44
pe/ring.erl
44
pe/ring.erl
|
@ -5,3 +5,47 @@
|
||||||
%% Write a similar program in some other programming language you are
|
%% Write a similar program in some other programming language you are
|
||||||
%% familiar with. Compare the results. Write a blog, and publish the
|
%% familiar with. Compare the results. Write a blog, and publish the
|
||||||
%% results on the internet!
|
%% results on the internet!
|
||||||
|
-module(ring).
|
||||||
|
-compile(export_all). % TODO: remove this
|
||||||
|
-record(message, {client=undefined, ttl=0, hops=0}).
|
||||||
|
|
||||||
|
%% What does a loop need to know? Who to forward to next.
|
||||||
|
%%
|
||||||
|
%% How does the last node know who to forward to? We need to pass the
|
||||||
|
%% parent in somehow.
|
||||||
|
%%
|
||||||
|
loop(Next) ->
|
||||||
|
receive
|
||||||
|
#message{client=Client, ttl=TTL, hops=Hops} ->
|
||||||
|
if TTL > 0 ->
|
||||||
|
Next ! #message{client=Client, ttl=TTL-1, hops=Hops};
|
||||||
|
true ->
|
||||||
|
Client ! #message{client=Client, ttl=TTL, hops=Hops}
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
%% gen_process ->
|
||||||
|
%% 1. is N > 0?
|
||||||
|
%% 1. Spawn process, use self() as next.
|
||||||
|
%% This generates processes in the reverse order, e.g.
|
||||||
|
%% this process is the last process in the chain.
|
||||||
|
|
||||||
|
gen_process(N) when is_number(N) ->
|
||||||
|
Root = self(),
|
||||||
|
Child = gen_process(Root, Root, N-1),
|
||||||
|
loop(Child).
|
||||||
|
|
||||||
|
gen_process(Root, _Parent, 0) ->
|
||||||
|
loop(Root);
|
||||||
|
|
||||||
|
gen_process(Root, Parent, Count) when Count > 0 ->
|
||||||
|
Child = gen_process(Root, Parent, Count-1),
|
||||||
|
loop(Child).
|
||||||
|
|
||||||
|
ring(N) ->
|
||||||
|
Root = spawn(fun () -> gen_process(N) end),
|
||||||
|
Root ! #message{client=self(), ttl=N, hops=0},
|
||||||
|
receive X ->
|
||||||
|
X
|
||||||
|
end.
|
||||||
|
|
51
pe/ring.go
51
pe/ring.go
|
@ -1,6 +1,53 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type Message struct {
|
type Message struct {
|
||||||
RCount int // how many times around the ring have we been
|
TTL int
|
||||||
FCount int // how many times has the message been forwarded
|
Parent chan Message
|
||||||
|
}
|
||||||
|
|
||||||
|
func process(from, next chan Message, id int) {
|
||||||
|
fmt.Printf("PID %d: from=%p, next=%p\n", id, from, next)
|
||||||
|
for {
|
||||||
|
message, ok := <-from
|
||||||
|
if !ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("process %d: message: %+v\n", message)
|
||||||
|
message.TTL--
|
||||||
|
if message.TTL == 0 {
|
||||||
|
message.Parent <- message
|
||||||
|
}
|
||||||
|
|
||||||
|
next <- message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func genProcess(count int) chan Message {
|
||||||
|
fmt.Printf("spawn: %p, count=%d\n", from, count)
|
||||||
|
next := make(chan Message, 0)
|
||||||
|
count--
|
||||||
|
go process(from, next, count)
|
||||||
|
if count == 0 {
|
||||||
|
return from
|
||||||
|
}
|
||||||
|
|
||||||
|
return genProcess(next, count)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
fmt.Println("startup")
|
||||||
|
entrypoint := make(chan Message, 0)
|
||||||
|
ring := genProcess(entrypoint, 3)
|
||||||
|
fmt.Printf("%p\t%p\n", ring, entrypoint)
|
||||||
|
time.Sleep(1)
|
||||||
|
rcv := make(chan Message, 0)
|
||||||
|
message := Message{3, rcv}
|
||||||
|
message = <-rcv
|
||||||
|
fmt.Println(message)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue