-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
128 lines (118 loc) · 3.62 KB
/
main.go
File metadata and controls
128 lines (118 loc) · 3.62 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
package main
import (
"fmt"
"math/rand"
"strings"
"sync"
"time"
)
// структура для хранения задачи
type Job struct {
Id int
URL string
}
// стуруктура для хранения результата выполнения задачи
type Result struct {
Job Job
Status bool
Duration time.Duration
}
// необходимые константы
const letterBytes = "abcdefghijklmnopqrstuvwxyz"
const NUM_WORKERS = 5
const NUM_JOBS = 30
const RESET = "\033[0m"
const C_RED = "\033[31m"
const C_GREEN = "\033[32m"
const STATUS_UP = C_GREEN + "Up " + RESET
const STATUS_DOWN = C_RED + "Down" + RESET
func worker(jobs <-chan Job, results chan<- Result, wg *sync.WaitGroup) {
defer wg.Done()
var randomDuration time.Duration
for job := range jobs {
//задаем случайную задержку
randomDuration = (time.Duration(rand.Intn(18)+2) * 100) * time.Millisecond
fmt.Printf("Do job - %d, with delay %v\n", job.Id, randomDuration)
//имитируем обработку задачи
time.Sleep(randomDuration)
//записываем результат в канал
results <- Result{job, rand.Intn(2) == 1, randomDuration}
}
}
func getRandomURL() string {
//вспомогательная функция, генерирует случайный URL
//генерируем случайный URL длиной 3-8 символов
var builder strings.Builder
//задаем протокол
if rand.Intn(2) == 1 {
builder.WriteString("http://")
} else {
builder.WriteString("https://")
}
//генерируем hostname
shortIDSize := rand.Intn(8-3) + 3
base := make([]byte, shortIDSize)
for i := range base {
base[i] = letterBytes[rand.Intn(len(letterBytes))]
}
builder.WriteString(string(base))
//генерируем домен
switch rand.Intn(5) {
case 0:
builder.WriteString(".com")
case 1:
builder.WriteString(".ru")
case 2:
builder.WriteString(".net")
case 3:
builder.WriteString(".org")
case 4:
builder.WriteString(".info")
}
return builder.String()
}
func main() {
rand.Seed(time.Now().UnixNano()) //инициализируем генератор случайных чисел
fmt.Println("Запуск системы мониторинга...")
//создаем необходимые каналы
jobs := make(chan Job, 10)
results := make(chan Result, 30)
var wg sync.WaitGroup
//запускаем пул воркеров
for i := 1; i <= NUM_WORKERS; i++ {
wg.Add(1)
go worker(jobs, results, &wg)
}
//заполняем канал задач
for j := 1; j <= NUM_JOBS; j++ {
jobs <- Job{j, getRandomURL()}
fmt.Printf("Job %d added\n", j)
}
close(jobs)
//ждем завершения воркеров, после чего закрываем канал с результатами
go func() {
wg.Wait()
close(results)
}()
//считываем результаты в срез
res := make([]Result, 0, NUM_JOBS)
for r := range results {
res = append(res, r)
}
//формируем итоговый очет
fmt.Println("Результаты мониторинга:")
var totalUp int
var totalDuration float32
var upDown string
for _, job_res := range res {
if job_res.Status {
totalUp++
upDown = STATUS_UP
} else {
upDown = STATUS_DOWN
}
fmt.Printf("%2.2d %21.21s %s %4.4v \n", job_res.Job.Id, job_res.Job.URL, upDown, job_res.Duration)
totalDuration = totalDuration + float32(job_res.Duration)
}
fmt.Printf("Итого проверено - %d хостов, доступно - %d%%, средняя задержка %v\n", len(res), totalUp*100/len(res), time.Duration(totalDuration/(float32(len(res)))))
}