-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathagrawala.go
More file actions
122 lines (114 loc) · 2.29 KB
/
agrawala.go
File metadata and controls
122 lines (114 loc) · 2.29 KB
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
package main
import (
"bufio"
"encoding/json"
"fmt"
"math/rand"
"net"
"os"
"time"
)
const myIp = "10.142.113.32"
type Info struct {
Tipo string
NodeNum int
NodeAddr string
}
type MyInfo struct {
cont int
first bool
nextNum int
nextAddr string
}
var chMyInfo chan MyInfo
var readyToStart chan bool
var addrs []string
var myNum int
func main() {
rand.Seed(time.Now().UTC().UnixNano())
myNum = rand.Intn(int(1e6))
fmt.Println(myNum)
var n int
fmt.Print("Ingrese la cantidad de nodos: ")
fmt.Scanf("%d\n", &n)
addrs = make([]string, n)
for i := 0; i < n; i++ {
fmt.Printf("Ingrese nodo %d: ", i+1)
fmt.Scanf("%s\n", &(addrs[i]))
}
readyToStart = make(chan bool)
go func() {
chMyInfo = make(chan MyInfo)
chMyInfo <- MyInfo{0, true, int(1e7), ""}
}()
go func() {
gin := bufio.NewReader(os.Stdin)
fmt.Print("Presione enter para iniciar...")
gin.ReadString('\n')
info := Info{"SENDNUM", myNum, myIp}
for _, addr := range addrs {
send(addr, info)
}
}()
server()
}
func server() {
host := fmt.Sprintf("%s:8000", myIp)
ln, _ := net.Listen("tcp", host)
defer ln.Close()
for {
conn, _ := ln.Accept()
go handle(conn)
}
}
func handle(conn net.Conn) {
defer conn.Close()
r := bufio.NewReader(conn)
msg, _ := r.ReadString('\n')
var info Info
json.Unmarshal([]byte(msg), &info)
fmt.Println(info)
switch info.Tipo {
case "SENDNUM":
myInfo := <-chMyInfo
myInfo.cont++
if info.NodeNum < myNum {
myInfo.first = false
} else if info.NodeNum < myInfo.nextNum {
myInfo.nextNum = info.NodeNum
myInfo.nextAddr = info.NodeAddr
}
go func() {
chMyInfo <- myInfo
}()
if myInfo.cont == len(addrs) {
if myInfo.first {
fmt.Println("Soy el primer!! :D")
criticalSection()
} else {
readyToStart <- true
}
}
case "START":
<-readyToStart
criticalSection()
}
}
func criticalSection() {
fmt.Println("Ha llegado mi turno!! :)")
myInfo := <-chMyInfo
if myInfo.nextAddr == "" {
fmt.Println("I was the last one! :(")
} else {
info := Info{Tipo: "START"}
fmt.Println(myInfo, info)
send(myInfo.nextAddr, info)
}
}
func send(remoteAddr string, info Info) {
remote := fmt.Sprintf("%s:8000", remoteAddr)
conn, _ := net.Dial("tcp", remote)
defer conn.Close()
bytesMsg, _ := json.Marshal(info)
fmt.Fprintln(conn, string(bytesMsg))
}