
Roman
18.10.2018
19:26:05
но это происходит где-то в недрах рефлексии
почему на tasks грешишь, не очевидно
Previous write at 0x00c0001b802c by goroutine 56:
github.com/qbeon/webwire-go.(*connection).deregisterTask()
D:/go-workspace/src/github.com/qbeon/webwire-go/connection.go:114 +0x7f
вот опять произошёл при десятой попытке

Vladimir
18.10.2018
19:27:52

Google

Vladimir
18.10.2018
19:28:05
У тебя запись в одно место возможна параллельно
Где то забыл лок

Aleksandr
18.10.2018
19:28:21
вот теперь все прояснилось

Vladimir
18.10.2018
19:28:26
Трейс есть же
Значит что в другом месте Лок не берешь или не тот берешь
Или рано отпускаешь

Roman
18.10.2018
19:31:17
Где то забыл лок
так я-ж говорю, тот код на который он ругается вообще-то под мутексом (previous write)
а read в рефлекте из-под testify/assert
вот полный лог

Vladimir
18.10.2018
19:31:41
Значит вокруг ассерта тоже

Roman
18.10.2018
19:32:42
мне кажется тут во всём виновата рефлексия которая лезет в недры защищённой структуры и пытается её прочитать параллельно с штатной записью
и думаю с этим вообще ничего не поделать

Vladimir
18.10.2018
19:33:16

Google

Vladimir
18.10.2018
19:33:22
Тот же

Roman
18.10.2018
19:34:20
Мьютекс вокруг рефлексии
дак как я это сделаю то?))
рефлексия происходит в коде тестов внутри assert'а от testify.
а изменения внутренностей объекта который реализует интерфейс Connection происходит в недрах библиотеки и защищена своим мутексом
понимаешь?

Vladimir
18.10.2018
19:34:43
понимаешь?
Я не понимаю в чём проблема тогда тестифай тоже обернуть

Roman
18.10.2018
19:37:06
Так тестифай значит тоже под мьютекс
дак они не могут делить мутекс)))
смотри...
- есть объект соединения, в нём сокет и каунтер задач которые на этом соединении обрабатываются
- при завершении обработки запроса каунтер декредментируется
- при новом запросе - инкрементируется
- эта операция защищена мутексом, каждый connection это thread-safe object
- структура connection реализует интерфейс Connection, который я выдаю наружу библиотеки
а тесты в этот интерфейс лезут с рефлексией и следственно в защищённые внутренности объекта и видимо поэтому происходит data race

Vladimir
18.10.2018
19:38:08

Roman
18.10.2018
19:40:09
т.е. решить это наверное можно так:
вместо:
require.Len(t, affectedConnections, 0)
пишем так
require.True(t, len(affectedConnections) == 0)
таким образом он в недры интерфейса лезть не должен а лишь проверить размер списка, что от него и ожидалось


Tishka17
18.10.2018
20:17:05
Подскажите, а можно как-то легко проверить что glide.lock содержит пакеты соответствующие glide.yml? Ну или после glide install проверить, что установленные пакеты удовлетворяют glide.yml

anatolii
18.10.2018
20:18:56
А лок разве не после успешного инстала генерится? Или ты не доверяешь ему?

Tishka17
18.10.2018
20:19:32
Лок после апдейта
Хочу его в гит коммитить
Чтобы версии фиксировать

anatolii
18.10.2018
20:20:12
Ну и ямль ведь в репозитории?

Tishka17
18.10.2018
20:20:24
Ну да

anatolii
18.10.2018
20:20:33
Не ты значит кто другой сгенерил по ямлю лок

Tishka17
18.10.2018
20:21:27
Ну да. Я хочу исключить ситуацию, что разработчик ямл изменил, а Лок не обновил

anatolii
18.10.2018
20:22:19
Если он изменил ямль а лок не сгенерил, значит останется старая версия и все будет работать хорошо

Google

Tishka17
18.10.2018
20:22:31
Понятно, что в большинстве случаев сборка упадет, но хочется более явно и надёжно

anatolii
18.10.2018
20:24:13
Не надо ходить в крайности. Не доверяйшь сам сгенери вчегда новый лок когда пришло изменение в ямл
Но я бы на твоем месте так не делал бы

Tishka17
18.10.2018
20:25:03
Так не хочу всегда генерить. Хочу его чтобы меняли как можно реже. Но раз в несколько месяцев кто-то забывает
Вопрос не в доверии а подстраховке

anatolii
18.10.2018
20:25:48
Что ж за люди тас у вас? Поменял версию и забыл поставить пакет?

Tishka17
18.10.2018
20:26:18
Да всяко бывает. Поспешил, задумался. И на ревью не заметишь такое
Обычная человеческая ошибка.

anatolii
18.10.2018
20:26:56
Да я, если честно, даже у джунов такого не встречал

Tishka17
18.10.2018
20:29:37
Ну а вы тоже Лок коммитите или всю папку вендор? Или генерируете его?

anatolii
18.10.2018
20:30:48
Лок

Pawel
18.10.2018
20:31:23

anatolii
18.10.2018
20:36:14
Соответственно, оно редко и тем сложнее понять
Я просто не понимаю как можно указать новую версию и забыть ее поставить. Человек ведь работает дальше, если он воспользуется чем-то обратно несовместимым, то билд не соберется, а если нет, то код будет работать как и раньше и в таком случае не надо париться

Tishka17
18.10.2018
20:36:42
Хуже если соберётся.

anatolii
18.10.2018
20:37:14
Какой файл? Лок что ли?

Tishka17
18.10.2018
20:37:19
Да
Либо я тебя не понимаю, либы ты меня

Google

anatolii
18.10.2018
20:38:29
Что за. Он же висеть будет в измененных. Ваши люди комитят не все изменения?

Tishka17
18.10.2018
20:38:32
Имхо, если можно автоматизировать проверку, надо автоматизировать. Если нельзя - ну и фиг с ней, потратим пять минут, решим руками
Ну то есть скорее всего почти все, но мало ли

Aleksandr
18.10.2018
20:40:57

Artem
18.10.2018
21:15:03
Вижу что нет. Ну вот оно так не будет работать, потому что он после вызова for ставит . на элемент массива

Roman
18.10.2018
21:25:55
https://[::]:9090/
это-ж у нас невалидный URL?
https://www.freeformatter.com/url-parser-query-string-splitter.html
вроде говорит мол валидный

Tishka17
18.10.2018
22:06:53
Хотя могу ошибаться

Roman
18.10.2018
22:07:31

Tishka17
18.10.2018
22:07:52
Аналог 0.0.0.0?

Roman
18.10.2018
22:08:19

Tishka17
18.10.2018
22:08:44
Ну в урле это странно

Roman
18.10.2018
22:18:00

Roman
18.10.2018
23:54:02
блин, это какой-то анекдот, проверил всё тщательнейшим образом локально, протестировал всё досконально, и GOMAXPROCS=1 и GOMAXPROCS=12, и с race detecter'ом и без, и все тесты, и только отдельные.. локально всё работает отлично.
Пушаю в master, запускается CI и фейлится 4 раза подряд на одной и той-же строке с DATA RACE WARNING ?
ну вот как? ?
GOCACHE=off естественно, но всё-равно никак не могу воспроизвести data race локально, а на CI она стабильно возникает

Сергей
19.10.2018
00:18:39

Google

Roman
19.10.2018
00:19:53
Не тот код небось
тот тот, я теперь таки после двадцатого запуска смог воспроизвести гонку
проблема вот тут: https://github.com/qbeon/webwire-go/blob/master/socketImpl.go#L111
и проблема очевидна и глупа, я конкурентно мутирую глобальную переменную пакета gorilla/websocket

Aleksandr
19.10.2018
02:25:35
.selectedTargets внутри .containers?
Нет это отдельный параметр в объекте который я передаю в шаблон вот https://github.com/sashaaro/docker-container-proxy/blob/e45e5aaf075add82dbe2e7fbd452fed1cdad7af5/dashboard.go#L66

Dmitri
19.10.2018
06:46:02
Та же фигня
Ну да, та же фигня
32-я строка
for {
message, err := bufio.NewReader(conn).ReadString('\n')
Я правильно понимаю, что вы на каждую строку новый bufio.NewReader создаете? Т.е. вы берете стрим, создаете ридер из него, читаете строку, дропаете ридер, берете стрим, создаете ридер - и так по кругу...
Я ведь правильно понимаю, что у вас задача - тупо запустить cmd локально и stdOut отдать на удаленную сторону, а то, что пришло оттуда - засунуть в stdIn?
Есть такая штука io.Copy(), вот она вам нужна

Vyacheslav
19.10.2018
06:53:26
привет
А насколько плохо давать двум страктам пустой метод, чтобы по нему исключительно загнать их в один интерфейс?

Pavel
19.10.2018
06:54:09
Это норм, если метод нигде не вызывается

Vyacheslav
19.10.2018
06:54:42
нигде, естественно

Pavel
19.10.2018
06:54:42
В нормальных языках можно интерфейс без метода делать — называется интерфейс маркёр.

Bohdan
19.10.2018
06:56:50
я бы задумался, если возникает такая ситуация - точно ли эти два стракта попадают под один интерфейс?

Pavel
19.10.2018
06:57:51
Ну естественно надо подумать. Но переделать если что всегда можно ?

Vyacheslav
19.10.2018
07:03:28

Pawel
19.10.2018
07:31:37

Alexander
19.10.2018
07:32:45
для жавы и шарпа вообще интерфейсы явно задают.
а зачем - ну примерно понятно. чтобы одним методом обрабатывать обе структуры

Pawel
19.10.2018
07:40:22
Зачем понадобился "пустой метод" и нафига искусственно загонять в один интерфейс?