
Roman
17.04.2018
12:07:47
newConnUpgrader - не экспортируется

Александр
17.04.2018
12:08:01
так поменяйте
сделайте его экспортируемым

Google

Roman
17.04.2018
12:08:22
так поменяйте
тогда добавится внешняя зависимость на gorilla/websocket

Александр
17.04.2018
12:08:30
c чего вы взяли?

Daniel
17.04.2018
12:08:37

Александр
17.04.2018
12:09:30
тогда оставить
я что-то путаю или если сделать публичным newConnUpgrader в коде https://github.com/qbeon/webwire-go/blob/master/socketImpl.go, то для внешних пакетов - "github.com/gorilla/websocket" не будет требовать импорта
c чего бы это он требовал

Roman
17.04.2018
12:09:46

Daniel
17.04.2018
12:09:50
не будет, конечно

Александр
17.04.2018
12:09:57
он используется только внутри

Roman
17.04.2018
12:10:15

Daniel
17.04.2018
12:10:16
вообще, есть такой фокус, с функцией, которая возвращает неэкспортируемый тип
тогда за пределами пакета его нельзя получить иначе, чем через эту функцию

Александр
17.04.2018
12:10:41

Daniel
17.04.2018
12:10:44
но и параметром нельзя передать никуда

Google

Александр
17.04.2018
12:10:45
насколько я понимаю

Daniel
17.04.2018
12:11:49

Roman
17.04.2018
12:12:59
вы их руками, что ли, менеджите?
честно говоря я ещё не работал с godep, просто не было времени изучить, поэтому пока ещё не понятно что делать с этим issue: https://github.com/qbeon/webwire-go/issues/2
я надеялся на то, что если gorilla/websocket будет в vendor'е внутри webwire-go тогда ничего вообще делать не нужно и webwire будет работать в любой среде свыше Go 1.5 без каких либо зависимостей
но возможно это не так, я ещё не знаю

Daniel
17.04.2018
12:14:58
я сейчас про goimport

Roman
17.04.2018
12:15:50
я-ж правильно понимаю что вложенный vendor ни одна система зависимотей включая godep не трогает?

Александр
17.04.2018
12:16:10
она как раз на нем и живет

Daniel
17.04.2018
12:16:32
ну и если вы передаете в функцию вебсокет - его придется сделать, а для этого придется пакет импортнуть палюбэ

Александр
17.04.2018
12:17:20
которая бы в этом же пакете создавал соедиенние
тогда не придется ничего тянуть

Roman
17.04.2018
12:18:07

Daniel
17.04.2018
12:18:57
нет, конечно

Roman
17.04.2018
12:19:30
понял, значит я в этом кардинально ошибался, я думал если в проекте есть сложенный vendor то его никто трогать не будет из вне

Александр
17.04.2018
12:42:07
c аргументом nil? ?

Google

Александр
17.04.2018
12:42:19
тогда вам не нужно экспортировать тот пакет

Roman
17.04.2018
12:43:09
c аргументом nil? ?
нил, не нил, экспортировать придётся:
func NewSocket(conn *"github.com/gorilla/websocket".Conn) *socket

Александр
17.04.2018
12:43:19
не придется

Daniel
17.04.2018
12:43:23
не придется

Александр
17.04.2018
12:43:52
если вы передаете nil это стандартный тип
если он допустим то все ок

Roman
17.04.2018
12:48:24
хмм
понял

Dima
17.04.2018
12:54:32
У меня есть функция rand.Intn(10)) при выполнении программы выдает одно и тоже число. Мне нужен генератор случайных rand.Seed. Как правильно написать функцию помогите


Roman
17.04.2018
12:54:55
всем привет. учу Go. прохожу A Tour of Go. вот такой код func Crawl(url string, depth int, fetcher Fetcher, cache *Cache, ch chan string) {
// TODO: Fetch URLs in parallel.
// TODO: Don't fetch the same URL twice.
// This implementation doesn't do either:
defer close(ch)
if depth <= 0 {
return
}
cache.mux.Lock()
if cache.visited[url] {
cache.mux.Unlock()
return
}
cache.visited[url] = true
cache.mux.Unlock()
body, urls, err := fetcher.Fetch(url)
if err != nil {
ch <- err.Error()
return
}
ch <- fmt.Sprintf("found: %s %q\n", url, body)
result := make([]chan string, len(urls))
for i, u := range urls {
go func(u string) {
result[i] = make(chan string)
Crawl(u, depth-1, fetcher, cache, result[i])
}(u)
}
for i := range result {
for res := range result[i] {
ch <- res
}
}
return
}
func main() {
cache := &Cache{visited: make(map[string]bool)}
ch := make(chan string)
Crawl("https://golang.org/", 4, fetcher, cache, ch)
for res := range ch {
fmt.Println(res)
}
}
выполняется с ошибкой "fatal error: all goroutines are asleep - deadlock!"


Roman
17.04.2018
12:54:55
никак не могу понять причину. может, кто посмотреть?

Daniel
17.04.2018
12:55:24
оформите его в play


Александр
17.04.2018
12:55:29
хмм
так что выносите все в отдельный пакет
всем привет. учу Go. прохожу A Tour of Go. вот такой код func Crawl(url string, depth int, fetcher Fetcher, cache *Cache, ch chan string) {
// TODO: Fetch URLs in parallel.
// TODO: Don't fetch the same URL twice.
// This implementation doesn't do either:
defer close(ch)
if depth <= 0 {
return
}
cache.mux.Lock()
if cache.visited[url] {
cache.mux.Unlock()
return
}
cache.visited[url] = true
cache.mux.Unlock()
body, urls, err := fetcher.Fetch(url)
if err != nil {
ch <- err.Error()
return
}
ch <- fmt.Sprintf("found: %s %q\n", url, body)
result := make([]chan string, len(urls))
for i, u := range urls {
go func(u string) {
result[i] = make(chan string)
Crawl(u, depth-1, fetcher, cache, result[i])
}(u)
}
for i := range result {
for res := range result[i] {
ch <- res
}
}
return
}
func main() {
cache := &Cache{visited: make(map[string]bool)}
ch := make(chan string)
Crawl("https://golang.org/", 4, fetcher, cache, ch)
for res := range ch {
fmt.Println(res)
}
}
вам нужно использовать waitgroup
если вы просто позапускаете гоурутины из main без ожидания
то основной процесс схлопнется до того как они успеют отработать
это и есть "all goroutines are asleep - deadlock!"


Roman
17.04.2018
12:56:51

Google

Александр
17.04.2018
12:57:33
попробуйте такой просто код
тест может быть любым
получите такую же ошибку

Roman
17.04.2018
12:57:58

Александр
17.04.2018
13:00:16
ждет
только чего вы ждете то?

Roman
17.04.2018
13:01:46
только чего вы ждете то?
завершения вот этого участка, потом defer close(ch)
for i := range result {
for res := range result[i] {
ch <- res
}
}

Александр
17.04.2018
13:04:04
стоит переосмыслить подход

Admin
ERROR: S client not available

Александр
17.04.2018
13:04:31
result[i] = make(chan string)
Crawl(u, depth-1, fetcher, cache, result[i])
вот это зачем?
вы же можете один раз создать ch в main и кормить его до посинения

Roman
17.04.2018
13:05:37
я не знаю, в какой момент его закрыть, если делать 1 канал

Александр
17.04.2018
13:05:43
fixed не тот кусок скопировал
а зачем вам его закрывать?
что бы приложение завершилось?

Roman
17.04.2018
13:06:38
да, в данном случае. чтобы завершить range

Александр
17.04.2018
13:07:00
вам нужно обработку канала вынести в отдельную гоурутину тоже
и сделать waitgroup

Google

Александр
17.04.2018
13:07:21
прочитайте про это
тогда не надо будет переживать по поводу закрылся ли канал

Roman
17.04.2018
13:08:12
т.е. в отдельной горутине объявить переменную, которая будет обеспечивать waitgroup?

Daniel
17.04.2018
13:08:15
waitgroup нужен там, где нет канала
если у нас уже есть канал - его надо просто закрыть в тот момент, когда вам поажется, что пора валить

Roman
17.04.2018
13:09:11
звучит прозрачно

Daniel
17.04.2018
13:09:13
а вот когда этот момент наступит, и как его дождаться, не завершив main - это вопрос к вам уже

Roman
17.04.2018
13:09:39
хорошо. много каналов - плохо?

Александр
17.04.2018
13:09:55
вы сами себя запутали с этими каналами

Daniel
17.04.2018
13:09:56
каналов нужно ровно столько, сколько вам нужно

Roman
17.04.2018
13:10:45
я открываю канал на каждый рекурсивный вызов, внутри которого я точно знаю, когда закрыть его. потом все сливаю в 1 канал и уже его жду в мэйне
мне кажется, нормальный подход

Daniel
17.04.2018
13:11:20
а?!
для начала - рекурсия это плохо

Александр
17.04.2018
13:11:44
Daniel передаю пациента вам ?

Daniel
17.04.2018
13:12:33
я простой парень
я сначала попрошу кода в play

Roman
17.04.2018
13:13:15

Sergey
17.04.2018
13:15:27

Daniel
17.04.2018
13:18:46