Adding some erlang stuff.

This commit is contained in:
Kyle Isom 2019-06-14 19:58:57 -07:00
parent 4aae9be7cd
commit 71975c1070
2 changed files with 93 additions and 2 deletions

View File

@ -5,3 +5,47 @@
%% Write a similar program in some other programming language you are
%% familiar with. Compare the results. Write a blog, and publish the
%% 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.

View File

@ -1,6 +1,53 @@
package main
import (
"fmt"
"time"
)
type Message struct {
RCount int // how many times around the ring have we been
FCount int // how many times has the message been forwarded
TTL int
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)
}