
Daniel
03.02.2017
12:25:12
Коллега

Антон
03.02.2017
12:25:32
пару пакетов я находил, но они так или иначе косячат(

Daniel
03.02.2017
12:25:41
Вы же, очевидно, не работали с этим
Нахера вы вообще отвечаете?

Google

Daniel
03.02.2017
12:26:10
Я вот молчу :)

Sergey
03.02.2017
12:27:11
Может офтоп, но я спрошу. Загуглил convex hull и хотел бы узнать какую, к примеру, задачу можно решить используя это? https://ru.wikipedia.org/wiki/%D0%92%D1%8B%D0%BF%D1%83%D0%BA%D0%BB%D0%B0%D1%8F_%D0%BE%D0%B1%D0%BE%D0%BB%D0%BE%D1%87%D0%BA%D0%B0 - вы же про это?
У меня так, праздный интерес )

Mars
03.02.2017
12:28:59
По моему где то в книге про Go, обсуждалась реализация этого алгоритма .. если мне не изменяет память

Антон
03.02.2017
12:31:26
У меня так, праздный интерес )
если вкратце, то существует алгоритм, называемый ray tracing, посволяющий описывать распространение различных волн в пространстве. На выходе этот алгоритм позволяет получить множество точек, описывающих покрытие какой-то плоскости
чтобы из этого множества точек сделать осмысленный замкнутый полигон нужен алгоритм convex hull
надеюсь, я понятно объяснил)

i
03.02.2017
12:33:10

Антон
03.02.2017
12:44:29

Mars
03.02.2017
12:55:17

Антон
03.02.2017
12:55:35
ладно, спасибо

Sergey
03.02.2017
13:51:40

Slava
04.02.2017
13:54:52
Фолкс, а вам интересны были бы практические курсы по линукс траблшутингу? (В формате реалтайм лаб и ctf)

Slach
04.02.2017
13:55:17
это про gops и go-torch ??

Google

Slava
04.02.2017
13:56:26
Не понял вопроса
Вообще не про го это

One
04.02.2017
14:04:29

Мерлин
04.02.2017
14:16:24

Amir
04.02.2017
14:16:49
Спасибо!

Мерлин
04.02.2017
14:17:17
https://www.gitbook.com/book/jannewmarch/network-programming-with-go-golang-/details
#free #book #книга

Slava
04.02.2017
14:28:42

Мерлин
04.02.2017
14:29:54

Михаил
04.02.2017
15:12:27

Slava
04.02.2017
16:03:33
спасибо за отзывы

Slach
04.02.2017
16:04:46
Линукс траблшутинг он разный бывает =)
формат CTF это конечно прикольно, но хорошо бы им безопасники занимались =)
а нам интересно в разрезе гошечки...

Slava
04.02.2017
16:07:19
CTF это вообще не про безопасность, это формат такой, может быть хоть про кормление грудью

Slach
04.02.2017
16:41:26
capture the flag with boobs ? Интересно посмотреть

Peter
04.02.2017
17:33:22
нет

分解物質
04.02.2017
17:36:25
кто-нибудь здесь пользуется goto в Go?

Мерлин
04.02.2017
17:39:46
Нет

Peter
04.02.2017
17:39:55
я иногда
и мне не стыдно

分解物質
04.02.2017
17:40:22

Peter
04.02.2017
17:40:35

Google

分解物質
04.02.2017
17:41:21
да нет в этом ничего такого

Мерлин
04.02.2017
17:41:46

分解物質
04.02.2017
17:42:10
ну там выйти из вложенного цикла
просто и понятно, без костылей
ошибки обработать

Мерлин
04.02.2017
17:43:40

分解物質
04.02.2017
17:44:50

?FLERRY?
04.02.2017
18:26:13
Не, goto - крайняя мера. А то видал код, в котором понашлепано. И так фиг прочтешь, а тут еще и goto...
годно :D

分解物質
04.02.2017
19:04:12

Oleh
05.02.2017
00:32:51
http://gobuffalo.io/
кто то юзал?
коментарии можно услышать?

?FLERRY?
05.02.2017
04:44:57

ros
05.02.2017
07:33:31

Stuf
05.02.2017
08:53:54

Slach
05.02.2017
09:29:27
народ а помогите
вот есть у меня боль =) я очевидно конкурентного программирования не понимаю =)
есть вот такой тип url.Values
объявлен он вот так
type Values map[string][]string
и есть вот такой код
buffered_data <- req.Form
на кол-ве конкурентных горутин 3000 в бенчмарке
я получаю
fatal error: concurrent map read and map write
вопрос
что у меня отправляется в канал???
копия мапы? или что-то другое?
если не копия, а нужна копия, то копию мапы мне руками придется создавать? или есть какой то clone волшебный?
и что делать со слайсами внутри мапы
они ж вроде как просто ссылки на часть массива

Daniel
05.02.2017
09:33:25
Отправляется сама мапа - это ссылочный тип, фактически
Копию - руками
но вот что мне не понятно
как так получилось, что в отправленную по каналу мапу кто-то пишет?

Google

Slach
05.02.2017
10:16:43
мне самому непонятно =(
вот ковыряюсь в стектрейсах
не могу найти где ж оно пишет то
там у меня в горутинах вот такой
в одной в состоянии running в стектрейсе вот такое
if form_value := form.Get(form_key); form_value != "" {
в другой в состоянии chan_send
g.buffered_data <- req.Form
и остальные либо в sleep
либо
form.Get это вот такой код
func (v Values) Get(key string) string {
if v == nil {
return ""
}
vs := v[key]
if len(vs) == 0 {
return ""
}
return vs[0]
}
ни одной горутины которая писала бы куда нибудь в похожее на form нет
либо sleep либо iowait состояния

Михаил
05.02.2017
10:18:18
>fatal error: concurrent map read and map write
если это паника то там будет стектрейс рядом

Slach
05.02.2017
10:23:12
да это паника
стектрейс там вот такой
https://gist.github.com/Slach/8c99f06602d1f2357bd937493ef84326
но там нету ни одной горутины которая бы пыталась писать хоть куда то

Admin
ERROR: S client not available

Slach
05.02.2017
10:23:40
в смысле писать в какую нибудь мапу

Daniel
05.02.2017
10:23:54
ну у меня есть совет

Slach
05.02.2017
10:24:16
с удовольствием послушаю

Daniel
05.02.2017
10:24:17
сделать свой тип, и мапу в нем полем
изменить тип канала для передачи своего типа
и посмотреть, где оно перестанет компиляться
там и запись

Slach
05.02.2017
10:25:05
а почему оно должно перестать компиляться???

Daniel
05.02.2017
10:25:58
потому, что типы совпадать перестанут


Slach
05.02.2017
10:35:13
так поменял тип канала
было
buffered_data chan url.Values
стало
buffered_data chan GAFormData
type GAFormData struct {
form url.Values
}
компиляться перестало ;)
и есть 4 места всего в коде где перестало компиляться
for {
select {
case form, ok := <-g.buffered_data:
if ok {
refresh_schema := false
for k := range form { // первое вот тут
это в горутине которая в единственном экземпляре читает канал
дальше там же
g.writeCSVRow(form)
внутри этой writeCSVRow процедуры в form вообще ничего не пишется
дальше запись в канал
g.buffered_data <- req.Form
и создание канала
buffered_data: make(chan url.Values, 100),
func (g *GA2ClickHouse) writeCSVRow(form url.Values) {
row := g.prepareCSVRow(form)
g.tsv_writer.Write(row)
g.writed_rows += 1
}
у меня все таки подозрение на слайсы а не на саму мапу
т.е. создается впечатление что когда в канал передали мапу в которой некоторое кол-во слайсов
кто-то пытается потом в эти слайсы писать из другой горутины
может такое приводить к подобной панике?


Константин
05.02.2017
10:38:07

Slach
05.02.2017
10:38:55
а можно сделать go test -race ?
это у меня в бенчмарках паника

Константин
05.02.2017
10:39:09
нужно

Slach
05.02.2017
10:39:59
сейчас попробую спасибо

Heorhi
05.02.2017
11:06:47
Всём привет. Может кто контейнер хороший с golang под docker compose посоветовать?

Slach
05.02.2017
11:08:19
вы правы, race есть
и аж двух местах
первое это вот такое
http://pastebin.com/CAnNdr3N
ну видимо действительно получается конкурентная запись и надо делать копию url.Values
а второй race это вот такой стектрейс, откуда в waitgroup рейс кондишен? я не понимаю =(((
http://pastebin.com/CNSktYtP

Google

Slach
05.02.2017
11:08:49
https://hub.docker.com/_/golang/

Мерлин
05.02.2017
11:10:03
Чисто технически можно в и scratch оборачивать

Константин
05.02.2017
11:10:30

Heorhi
05.02.2017
11:14:43

Мерлин
05.02.2017
11:15:28

Slach
05.02.2017
11:22:29
wait нельзя вызывать до первого add, это в доках написано
хмм...
дак он у меня wait вроде до первого add и не вызывается
для копирования form
сделал вот такой кастыль
// WTF race condition for form??
func CopyFormData(form url.Values) (url.Values){
new_form := url.Values{}
for k,v:= range form {
new_v := make([]string,len(v))
copy(new_v, v)
new_form[k] = new_v
}
return new_form
}
сразу вопрос
для form в этой функции память же на стеке выделяется? может проще тогда сразу return сделать???
или это опять будет "копия ссылочного типа"? и я таки правильно делаю что копирую полностью все данные??

Daniel
05.02.2017
11:39:36
копия - ок
но
кто, все же, в нее пишет, и зачем?

Slach
05.02.2017
11:44:03
так после CopyFormData ушел RACE с конкурентной записью в map =)
я понял что у меня код бенчмарка не правильный ;)))
там единый экземпляр req.Form был и пишет в нее другая горутина бенчмарка который runParallel делает

Slava
05.02.2017
11:44:42
почему кто-то вообще пишет в req.Form?
это данные для чтения только


Slach
05.02.2017
11:47:23
ну с чего бы вдруг?? а метод Set там зачем?
я ОБОГАЩАЮ данные всякими там geoip и user-agent парсингами
90% данных приходит в запросе
10% это обогащение
теперь ГЛАВНЫЙ вопрос остался, каким образом wg.Wait может вызваться быстрее чем wg.Add ...
вот это я уже реально не понимаю
вот есть у меня код бенчмарка
func BenchmarkGA2ClickHouse_CollectParallel(b *testing.B) {
g := prepareCollectorToBenchmark()
go g.ProcessRequest() //вот тут первой строкой идет g.wg.Add(1)
defer g.ShutdownCollector() //вот тут идет close(g.bufferred_data) и потом g.wg.Wait()
log.Printf("b.N=%d", b.N)
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
rw := web.ResponseWriter(testResponseWriter{})
// вот тут
for pb.Next() {
req := NewTestRequest()
g.Collect(rw, &req) //вот тут у меня пишется в канал g.buffered_data на который ProcessRequest читает
}
})
}
я правильно понимаю что у меня shutdown collector из defer стартует раньше ProcessRequest потому что порожается куча горутин который в runParallel ???