-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
156 lines (131 loc) · 3.21 KB
/
main.go
File metadata and controls
156 lines (131 loc) · 3.21 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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package main
import (
"fmt"
"math/rand"
"sync"
"time"
)
var random *rand.Rand
var inputRoad1Pool []int
var inputRoad2Pool []int
var inputRoad3Pool []int
var inputRoad4Pool []int
var ouputRoad1ch chan int
var ouputRoad2ch chan int
var ouputRoad3ch chan int
var ouputRoad4ch chan int
func init() {
s := rand.NewSource(time.Now().UnixNano())
random = rand.New(s)
}
func randomRange(min, max int) int {
return random.Intn((max-min)+1) + min
}
func main() {
var wg sync.WaitGroup
fmt.Println("Starting a party...")
var circle = make(chan int, 8)
ouputRoad1ch = make(chan int)
ouputRoad2ch = make(chan int)
ouputRoad3ch = make(chan int)
ouputRoad4ch = make(chan int)
wg.Add(9)
go circlePool(circle, &wg)
go inputRoad1(circle, &wg)
go inputRoad2(circle, &wg)
go inputRoad3(circle, &wg)
go inputRoad4(circle, &wg)
go outputRoad1(&wg)
go outputRoad2(&wg)
go outputRoad3(&wg)
go outputRoad4(&wg)
wg.Wait()
fmt.Println("Main goroutine exits")
}
func circlePool(circle chan int, wg *sync.WaitGroup) {
defer wg.Done()
for car := range circle {
carDistribution(car)
}
}
func DrivingForNSecs(nSecs int) {
time.Sleep(time.Duration(nSecs) * time.Second)
}
func carDistribution(car int) {
switch car {
// cases represents the exit number
case 1:
{
DrivingForNSecs(1)
ouputRoad1ch <- car
}
case 2:
{
DrivingForNSecs(2)
ouputRoad2ch <- car
}
case 3:
{
DrivingForNSecs(3)
ouputRoad3ch <- car
}
case 4:
{
DrivingForNSecs(4)
ouputRoad4ch <- car
}
}
}
func inputRoad1(circle chan int, wg *sync.WaitGroup) {
defer wg.Done()
processInputRoad(circle, inputRoad1Pool, (time.Duration(random.Intn(5)) * time.Second))
}
func inputRoad2(circle chan int, wg *sync.WaitGroup) {
defer wg.Done()
processInputRoad(circle, inputRoad2Pool, 1*time.Second)
}
func inputRoad3(circle chan int, wg *sync.WaitGroup) {
defer wg.Done()
processInputRoad(circle, inputRoad3Pool, 2*time.Second)
}
func inputRoad4(circle chan int, wg *sync.WaitGroup) {
defer wg.Done()
processInputRoad(circle, inputRoad4Pool, 100*time.Millisecond)
}
func outputRoad1(wg *sync.WaitGroup) {
defer wg.Done()
processOutputRoad(ouputRoad1ch, time.Duration(random.Intn(5))*time.Second)
}
func outputRoad2(wg *sync.WaitGroup) {
defer wg.Done()
processOutputRoad(ouputRoad2ch, 1*time.Second)
}
func outputRoad3(wg *sync.WaitGroup) {
defer wg.Done()
processOutputRoad(ouputRoad3ch, 1*time.Hour)
}
func outputRoad4(wg *sync.WaitGroup) {
defer wg.Done()
processOutputRoad(ouputRoad4ch, 100*time.Millisecond)
}
// =======PROCESSING FUNCTIONS=============
func processOutputRoad(outputRoad chan int, d time.Duration) {
for car := range outputRoad {
fmt.Println(fmt.Sprintf("Car drove out [%d] exit", car))
time.Sleep(d)
}
}
func processInputRoad(circle chan int, inputRoadPool []int, d time.Duration) {
for {
//random in range to determine what exit to drive
inputRoadPool = append(inputRoadPool, randomRange(1, 4))
//We send a car to circle if possible, otherwise skip and generate another set of cars for the next second
select {
case circle <- inputRoadPool[0]:
fmt.Println(fmt.Sprintf("Car drove into circle. To drive out on %d exit", inputRoadPool[0]))
inputRoadPool = inputRoadPool[1:]
default:
}
time.Sleep(d)
}
}