
Alexander
21.01.2018
11:57:24
Про последние три строчки

Мерлин
21.01.2018
11:57:53

Alexey
21.01.2018
11:58:25

Google

Alexander
21.01.2018
12:00:11
Я думаю, просто некоторые хосты вернули ошибку и горутина не записала ответ в канал. Поэтому количество не сходится

Alexey
21.01.2018
12:01:00
results <- fmt.Sprintf("Thread %d: %v\n", thread, err)
Она возвращает 3 результата и на этом просто стоит прога
Ничего не делая, при этом не выходит
for w := 0; w < len(hosts); w++ тут я имею ввиду

Alexander
21.01.2018
12:03:38
Аа, ну правильно!

Alexey
21.01.2018
12:03:58
Объясни, пожалуйста, с чем связано, я хоть пойму)

Alexander
21.01.2018
12:04:00
Горутина же не читает из канала циклически
Каждая обрабатывает только одну задачу

Alexey
21.01.2018
12:04:26
то есть если я это упакую в for{}, то сработает?

Alexander
21.01.2018
12:05:15
Погоди, гляну доку на x/ssh

Google

Alexey
21.01.2018
12:07:07
Не над

Alexander
21.01.2018
12:07:15
Хм, а что за пакет такой вообще? Есть x/crypto/ssh

Alexey
21.01.2018
12:07:31
Я руками сам
Без пакета

Mykyta
21.01.2018
12:07:47
close(jobs) никогда не выполнится

Alexey
21.01.2018
12:07:53
Он не подходит мне

Alexander
21.01.2018
12:08:15
Тогда покажи, что делает ssh.Scan

Alexey
21.01.2018
12:08:47
Да перезагрузка комп, повесил случайно

Alexander
21.01.2018
12:10:46

Alexey
21.01.2018
12:11:56
package ssh
import (
"fmt"
"net"
"time"
)
func Scan(thread int, jobs <-chan string, results chan<- string) {
for j := range jobs {
_, err := net.DialTimeout("tcp", j+":22", 5*time.Second)
if err != nil {
results <- fmt.Sprintf("Thread %d: %v\n", thread, err)
return
}
results <- fmt.Sprintf("Thread %d: %s port is opened.\n", thread, j)
}
}
Это вот сама функция scan

Alexander
21.01.2018
12:16:10
https://play.golang.org/p/GmCueoKFXIj
всё работает как надо

Alexey
21.01.2018
12:17:28
То есть этот код можно считать хорошим?
Просто вопрос был в том, что если у меня хостов например будет миллион, то я же не смогу позволить отработать миллион горутин

Alexander
21.01.2018
12:18:47
Да, я сначала не понял, как именно работает ssh.Scan. Но так как он читает задачи из канала, то всё в целом правильно.
Я бы только не стал делать канал с таким буфером - это бессмысленно

Michael
21.01.2018
12:19:34
и беспощадно

Alexey
21.01.2018
12:19:38
Простой небуфиризированный сделать?

xPushkin
21.01.2018
12:19:44

Google

Michael
21.01.2018
12:19:53
но когда хочется и колится, то можно

Alexander
21.01.2018
12:19:59
Да. Только читающую горутину запусти _сначала_

Alexey
21.01.2018
12:20:13
Почему нет?
Ну я пока не силен в го, вот и решил уточнить) По верному пути ли я иду

xPushkin
21.01.2018
12:20:31

Alexander
21.01.2018
12:21:28

xPushkin
21.01.2018
12:21:50

Alexey
21.01.2018
12:22:03

Alexander
21.01.2018
12:22:13
Это правильно, да.

xPushkin
21.01.2018
12:22:20
Я думал у вас миллион коннектов

Alexey
21.01.2018
12:22:47
Всем спасибо, очень помогли) А то сижу со вчера и думаю как реализовать)

Michael
21.01.2018
12:24:11
хорошо реализовывать надо) и про балансировку нагрузки на сеть не забывай

Alexey
21.01.2018
12:28:10
А так по честному, не очень у меня на го? Да?
Я просто до этого на питоне бацал

Michael
21.01.2018
12:30:35
у всех не очень и все живут

Alexey
21.01.2018
12:32:11
)) Да вот только начал недавно) так в основном по вебу мелочевку всякую писал

Max
21.01.2018
13:16:27
Кто использует fasthttp вместо net/http?
Какие минусы кроме поддержки http2?
Чистый или с каким-то микрофреймворком?

Michael
21.01.2018
13:17:36
у фастхттп были юзкейсы кмк
подходит для задач - используй

Google

Michael
21.01.2018
13:17:58
не подоходит - не используй

Max
21.01.2018
13:41:27

Alexey
21.01.2018
13:42:12
А wg на самом деле не очень подходит пока что, сейчас буду думать
Почитаю, посмотрим) Если интересно будет потом могу отписать, как решил это

Michael
21.01.2018
13:44:53
запускаю нужное кол-во рутин, они слушают канал с тасками, когда канал закрываю, то и рутины завершаются
воркеры с манагером общаются аля Task & TaskResult сообщениями

Alexey
21.01.2018
13:45:40
и отслеживать одновременное кол-во запущенных, но не помню почему отмел эту идею

Michael
21.01.2018
13:46:42
как наваяешь, лучше код покажи
кто нить да подскажет

Alexey
21.01.2018
13:47:20
Ну да, наверное так и сделаю, но пока проблем нет вроде

Alexander
21.01.2018
13:47:54
WaitGroup (да, я ошибся, когда назвал их WorkerGroup) нужен чтобы не отслеживать количество результатов, а просто дождаться пока все горутины отработают. Вот пример - https://golang.org/pkg/sync/#example_WaitGroup

Max
21.01.2018
13:48:07
Это классическая задача решается или через семафоры или через thread pool. По крайней мере в оствльных языках

Alexey
21.01.2018
13:49:08

Alexander
21.01.2018
13:49:55
Если сделаешь чтение или запись в отдельной горутине, как я рекомендовал выше (чтобы буфер в канале не делать равным количеству данных), то ожидание завершения работы горутин станет актуальным.

Alexey
21.01.2018
13:51:50

Alexander
21.01.2018
13:56:14
Вот с записью в отдельной горутине и канал без буфера - https://play.golang.org/p/E725utf5Et_X
Можно сделать наоборот - считывать в отдельной горутине, а записывать в основном потоке
Главное - чтобы и запись и чтение работали одновременно

Alexey
21.01.2018
13:57:46
Хм

Google

Alexey
21.01.2018
13:58:15
Ща попробую
Погоди, а вот ожидание завершения у меня происходит же по сути по освобождению данных из канала, то есть то что я сделал запись в отдельной горутине, мало что поменяло вроде, единственное, что к ней нужен будет waitgroup
Или я ошибаюсь?
Ну то есть пока я не освобожу канал полностью, горутина не перестанет работать
Так же?
Я может быть не так что - то понимаю

Michael
21.01.2018
14:04:31
в мейне создаю несколько воркеров

Alexander
21.01.2018
14:04:31
WaitGroup тут пока не нужен, т.к. всё еще есть подсчет задач. А смысл изменения - убрать буфер у канала и сохранить немного памяти (ну или много)

Michael
21.01.2018
14:05:02
а... оптимизируете)

Alexey
21.01.2018
14:06:27
А, понял. Просто еще с объемами данных такими не успел столкнуться, надо бы попробовать поигратьсья с огромным кол-вом данных

Michael
21.01.2018
14:07:47
для моих задач работает такой вариант
создаём два канала - один для таском, другой для done сообщений или результатов
поднимается нужно кол-во горутин
при завершении канал с тасками закрывает
начинаем вычитывать done сообщения (тут есть блокировка осн потока выполнения)
как все отчитались, так и завершаем выполнение

Alexander
21.01.2018
14:09:04

Michael
21.01.2018
14:09:10

Alexander
21.01.2018
14:10:00
да
Ну так тоже можно, да. Только WaitGroup же сделан именно для этого.

Michael
21.01.2018
14:10:22

Alexey
21.01.2018
14:10:30

Michael
21.01.2018
14:11:54

Alexey
21.01.2018
14:12:26
Я вот как переделал сейчас
package main
import (
"flag"
"fmt"
"log"
"sync"
"x/ssh"
)
func main() {
var wg sync.WaitGroup
pool := flag.String("p", "", "IP format 192.168.1.0/24")
flag.Parse()
// 64.254.32.0/24
hosts, err := ssh.GenerateHosts(*pool)
if err != nil {
log.Fatalf("[ERROR] %v\n", err)
}
results := make(chan string, 5)
for _, host := range hosts {
wg.Add(1)
go func(host string) {
wg.Done()
ssh.Scan(host, results)
}(host)
}
wg.Wait()
for i := 0; i < len(hosts); i++ {
fmt.Print(<-results)
}
}