@gogolang

Страница 869 из 1630
Stanislav
27.02.2018
15:59:40
Это я про предыдущую тему о базе
Прошу прощения, не там пальцем провел) это на сообщение выше писал

Andrey
27.02.2018
15:59:53
Короче, надо навернуть атомик, ок

Пойду попробую вызвать панику при смене указателя

Alexey
27.02.2018
16:01:32
В вашем случае sync.RWMutex

Google
Alexey
27.02.2018
16:01:55
Если большинство читает

Andrey
27.02.2018
16:02:07
И то верно

Stanislav
27.02.2018
16:02:20
Пойду попробую вызвать панику при смене указателя
В любом случае хорошее правило - если читает/пишет больше одного, то мьютекс

Andrey
27.02.2018
16:07:11
Но все же. https://4gophers.ru/articles/konkurentnost-v-go-gonki/

Вот в статье пример, где программа с состоянием гонки не вызывает панику

(при этом, в моём вопросе не имеет значения корректность результата)

Значит ли это, что можно не заморачиваться с синхронизацией?)

Maxim
27.02.2018
16:10:57
Значит ли это, что можно не заморачиваться с синхронизацией?)
Гонка не вызывает панику, она вызывает непредсказуемое поведение приложения, что намного хуже чем паника.

Andrey
27.02.2018
16:11:36
Гонка не вызывает панику, она вызывает непредсказуемое поведение приложения, что намного хуже чем паника.
Я же говорю, что меня устраивает, что будет прочитан старый указатель. Это (для меня) предсказуемое поведение.

Maxim
27.02.2018
16:12:23
Тогда пожалуйста

The
27.02.2018
16:13:10
И ты перед каждым запросом коннект типа поднимаешь?
С чего это вдруг? Речь идет вот о чем: 1. Пришел запрос от клиента, берем наш *sql.DB 2. В это время наша горутина устанавливает коннект и в переменную database.DB пишет то, что вернул sql.Open. Что это? Не гонка разве?

Zver
27.02.2018
16:17:38
Я же говорю, что меня устраивает, что будет прочитан старый указатель. Это (для меня) предсказуемое поведение.
Это пока устраивает. А потом не будет устраивать, но забудется и придется искать причину ошибки. Так что лучше сразу нормально сделать.

Google
The
27.02.2018
16:18:11
Какая разница что там внутри

Евгений
27.02.2018
16:18:55
это был вам намёк, что делом надо заниматься, а не призрачный тест кавердж блюсти
возможно, но удобно видеть, когда вдруг какой-то тест случайно оторвал

Alexey
27.02.2018
16:19:06
Какая разница что там внутри
Ты ещё мутексы мутексами оборачивай

The
27.02.2018
16:19:20
sql.Open() возвращает у тебя в DB, в этот момент ты берешь database.DB и обращаешься к нему.

объясните ему кто-то

когда коннект установился, понятно что внутри concurrent safe

Andrey
27.02.2018
16:20:24
Это пока устраивает. А потом не будет устраивать, но забудется и придется искать причину ошибки. Так что лучше сразу нормально сделать.
=) это продуманное решение в пользу быстродействия. Задача была сэкономить такты на лочках при подмене одного кеша другим (кеш в сложной структуре с мапами, поэтому просто подменяем указатели). При этом какой кеш успел прочитать клиент - не принципиально, критична именно скорость ответа.

Alexey
27.02.2018
16:20:49
sql.Open() возвращает у тебя в DB, в этот момент ты берешь database.DB и обращаешься к нему.
В какой этот, ты делаешь Open() по сути ещё даже с базой соединение не устанавливается.

The
27.02.2018
16:22:23
ладно, забей

Maxim
27.02.2018
16:22:27
Это пока устраивает. А потом не будет устраивать, но забудется и придется искать причину ошибки. Так что лучше сразу нормально сделать.
Если задача требует высокой производительности, мьютексы являются узким местом (а они не то чтобы очень быстрые) и в софте race не приведет к пиздецу то можно и выпилить.

Правда пример такого софта я не могу привести) Но есть софт где локи много выедают.

Alexey
27.02.2018
16:23:29
go-database-sql.org/accessing.html Perhaps counter-intuitively, sql.Open() does not establish any connections to the database, nor does it validate driver connection parameters. Instead, it simply prepares the database abstraction for later use. 

Andrey
27.02.2018
16:24:44
go-database-sql.org/accessing.html Perhaps counter-intuitively, sql.Open() does not establish any connections to the database, nor does it validate driver connection parameters. Instead, it simply prepares the database abstraction for later use. 
Самое интересное, что он даже не проверяет, что соединение может быть установлено. Поэтому после этого мы при ините вызываем db.Ping() Чтобы оно проверило и ругнулось в случае чего

The
27.02.2018
16:25:57
ладно, забей

Alexey
27.02.2018
16:31:46
ладно, забей
Смотри https://github.com/Supme/gonder/blob/master/models/config.go#L33 Это потом используется во всём приложении и для рассылки в тысячи потоков и для статистики и для апи. Если не ограничить коннекты к базе, то база будет через какое то время делать отлуп

Andrey
27.02.2018
16:32:17
Правда пример такого софта я не могу привести) Но есть софт где локи много выедают.
Еще очень интересно как работает RWMutex. Допустим есть 1000 горутин, которые вызвали RLock() и в этот момент читают данные. Вызываем в другой рутине Lock(), она будет ждать пока эта 1000 дочитает, это предсказуемо. Но в тоже время, если у нас появятся еще 500 читателей, то они будут ждать пока первая 1000 дочитает, потом, когда запишется и только потом смогут получить свои данные и это мне показалось несколько странно. Потому, что за это время уже можно ответить на запросы из тех данных, что есть.

Google
Andrey
27.02.2018
16:34:09
Lock приоритетнее чем RLock
Lock будет ждать пока существующие RLock не разблокируются. И заблокирует все новые RLock.

Alexey
27.02.2018
16:35:21
поднимать коннект в init, это шляпа
Нормально работает, а тот селект 1 это проверка что не голая база

Инит один раз происходит

Maxim
27.02.2018
16:36:47
Lock будет ждать пока существующие RLock не разблокируются. И заблокирует все новые RLock.
Да, ты же можешь изменить данные поэтому и остальные читатели ждут, потому что ты уведомил их что сейчас будешь что-то изменять.

The
27.02.2018
16:37:35
Нормально работает, а тот селект 1 это проверка что не голая база
я ж говорю, в твоем случае, да, и пусть весь мир подождет, пока твой инит поднимет коннект и удостоверится. в других приложениях иногда важно не копить в пул коннекты, особенно если прет сильный трафик, твоему серверу просто не дадут подняться и разгрести всю работу. проще начать отшивать коннекты по одному, после чего, когда база поднимется, уже отвечать реальным ответом рабочим, а не ошибкой.

Maxim
27.02.2018
16:38:33
Zver
27.02.2018
16:38:35
Andrey
27.02.2018
16:39:59
Я сейчас либо найду информацию что указатель при состоянии гонки может повредиться, либо так и оставлю.

Maxim
27.02.2018
16:41:17
Я не понимаю, что показалось странным.
Вторые 500 читателей появились уже после того как я уведомил, что хочу изменить данные. Что в этом странного)

Andrey
27.02.2018
16:42:54
Вторые 500 читателей появились уже после того как я уведомил, что хочу изменить данные. Что в этом странного)
В том, что если вас устраивает, что они могут получить за время лока старые данные и это будет корректно - то они лочатся напрасно.

The
27.02.2018
16:43:48
ещё разок

Alexey
27.02.2018
16:44:14
я ж говорю, в твоем случае, да, и пусть весь мир подождет, пока твой инит поднимет коннект и удостоверится. в других приложениях иногда важно не копить в пул коннекты, особенно если прет сильный трафик, твоему серверу просто не дадут подняться и разгрести всю работу. проще начать отшивать коннекты по одному, после чего, когда база поднимется, уже отвечать реальным ответом рабочим, а не ошибкой.
После рассылок в сотни тысяч, люди сотнями в секунду открывают письма, даже, в эти моменты рестартовали, не потеряв ни одного открытого письма в статистике, потому что когда рестартуем, http сервер не слушает, он начинает слушать когда всё готово, для клиентов это затык в сети меньше чем 100мс

Andrey
27.02.2018
16:44:31
Юзайте пакет unsafe) Только осторожно)
какую именно возможность из него стоит изучить?

Maxim
27.02.2018
16:49:30
какую именно возможность из него стоит изучить?
Ну, возможность у него одна - читать и записывать произвольную память. С тех времен как конкуретное чтение мапок стало алертить он спасает)

Google
Andrey
27.02.2018
16:50:02
Ну, возможность у него одна - читать и записывать произвольную память. С тех времен как конкуретное чтение мапок стало алертить он спасает)
охох) нет, это не наш выбор. мы пошли намного более безопасным и быстрым путём в вопросе параллельной записи и чтения мап

Хотя и чуть более отъедает память

Andrey
27.02.2018
16:53:44
Шардирование?
Нет. У нас задача как можно быстрее отдавать ответ, не меняя данные в процессе ответа. Поэтому мы имеем "кеш" в работе, который только читается и для всех новых клиентов подменяем указатель на новый прогретый кеш.

Поэтому в существующем кеше нет состояния гонки в мапах (они только читаются) и при этом мы имеем возможность кеш обновлять.

Admin
ERROR: S client not available

Andrey
27.02.2018
16:55:06
Не понял вашего вопроса

Если горутины уже не будут ссылаться на старый кеш - он его соберет

Если будут ссылаться - не соберет. Логично же?

Alexey
27.02.2018
16:55:48
Не понял вашего вопроса
И попортит данные предыдущие

Andrey
27.02.2018
16:55:57
Zver
27.02.2018
16:56:36
А как вы заполняете второй кэш?

Andrey
27.02.2018
16:56:37
Указатель будет замкнут в горутине. Почему сборщик может попортить данные?

А как вы заполняете второй кэш?
В отдельной горутине

Там все медленные процессы хождения в базу и подготовки данных

Zver
27.02.2018
16:57:09
А если в момент подмены ещё и сборщик придёт?
Он их не соберет, пока используется.

Zver
27.02.2018
16:57:42
Google
Andrey
27.02.2018
16:57:55
По порядку)

Alexey
27.02.2018
16:58:01
А, понял рабочая ссылка одна, а меняем её на обновлённую в которой данные, ок.

Maxim
27.02.2018
16:58:16
По порядку)
Да не, можно не отвечать уже) Я понял, тогда ваш костыль будет норм работать)

Andrey
27.02.2018
16:59:20
1. На каждый запрос мы в канал пишем id сущности которую запросили 2. В отдельной горутине канал слушаем и проверяем, что данные устарели (были обновлены n секунд назад) или вообще не сущетсвуют 3. Обновляем 4. Меняем указатель

Магия, но быстрее решения не придумал

Maxim
27.02.2018
17:01:11
Магия, но быстрее решения не придумал
а bigcache пробовали? Я не уверен что он быстрее, но он очень интересно хранит данные в одной куче и по оффсетам достает. Должно быть очень быстро и конкуретно)

Zver
27.02.2018
17:03:12
Магия, но быстрее решения не придумал
Есть вероятность, что все гоурутины встанут в ожидании, пока наполнитель кэша будет обрабатывать данные на пополнение кэша.

Andrey
27.02.2018
17:03:16
а, кстати, я его изучал. Шардирование - тоже рассматривали как вариант. Но он внутри все равно с лочками. И в нашем варианте выглядит все проще.

Alexey
27.02.2018
17:03:44
А какая нагрузка то?

Andrey
27.02.2018
17:04:17
А какая нагрузка то?
Да никакой) просто развлекаюсь

Zver
27.02.2018
17:05:51
Почему?
Потому что запись в канал блокирующая операция (в которой, кстати мютексы используются) и пока данные не изымут из канала горутина будет висеть. Либо делать буфер с запасом.

Andrey
27.02.2018
17:05:52
В проде сейчас в среднем 800 запросов в секунду, но там пхп и тоже все оптимизированно, что даже на 10% проц не грузит.

Alexey
27.02.2018
17:05:53
Гошка с шаблонами штатными гигабитный канал запросто забивала, причём был ещё xorm но с включеным кэшем

Andrey
27.02.2018
17:07:06
Покажите.
select{ case ch <- id: case default: }

Страница 869 из 1630