
The
27.02.2018
17:07:59
Можно шардить мапы, в каждой мапе есть RWMutex, сами сущности кеша через бинарный семафор и закрытый канал работают. Если канал закрыт, чтение мгновенное, отдаем значение. Если канал открыт, тогда за значением уже кто-то пришел, стоит очередь, и когда значение получено, канал закрывается и все получают свои значения. Т.о. чтение значения entity сопровождается чтением из канала в пустоту.
Сами мапы можно и без RWMutex сделать на каналах. Но каналы по 100 нс выжирают.
Это как раз ваш кейс, когда за одним значением пришло несколько горутин, все получат один и тот же ответ, полученный единоразово из базы или откуда-то.


Andrey
27.02.2018
17:08:58
Можно шардить мапы, в каждой мапе есть RWMutex, сами сущности кеша через бинарный семафор и закрытый канал работают. Если канал закрыт, чтение мгновенное, отдаем значение. Если канал открыт, тогда за значением уже кто-то пришел, стоит очередь, и когда значение получено, канал закрывается и все получают свои значения. Т.о. чтение значения entity сопровождается чтением из канала в пустоту.
Сами мапы можно и без RWMutex сделать на каналах. Но каналы по 100 нс выжирают.
Это как раз ваш кейс, когда за одним значением пришло несколько горутин, все получат один и тот же ответ, полученный единоразово из базы или откуда-то.
Ваше решение медленнее

Alexey
27.02.2018
17:10:08

The
27.02.2018
17:10:09
вы на глаз определили? или как? конечно держать извечно прогретый кеш и подменять указатель будет быстрее, но по памяти - вряд ли.

Google

The
27.02.2018
17:11:04
к слову, в вашем кейсе вместо того чтобы копить очередь на открытом канале, можно отдавать oldValue, который создан перед тем как пойти за значением

Andrey
27.02.2018
17:11:09

Daniel
27.02.2018
17:11:31
коллеги, что тут у вас за содомия?

Zver
27.02.2018
17:13:05

The
27.02.2018
17:13:10

Zver
27.02.2018
17:14:30

Andrey
27.02.2018
17:14:59

Zver
27.02.2018
17:16:16

Andrey
27.02.2018
17:16:44

Daniel
27.02.2018
17:17:09
практически - не надо это выяснять. хотите атомарно подменять указатель - используйте atomic

Google

Andrey
27.02.2018
17:17:57
теоретически - да
я слышал, что ось защищает от такого. но моих знаний не хватает, чтобы нагуглить как это внутри устроено.

Maxim
27.02.2018
17:18:07
Он не хочет атомарно)

The
27.02.2018
17:18:29
подменить поинтер это вообще атомарная операция, каков смысл на ней экономить?

Andrey
27.02.2018
17:19:04

The
27.02.2018
17:19:36

Andrey
27.02.2018
17:19:44

The
27.02.2018
17:20:06
я бы мог дать вам ссылку, но вы сильно язвите, поэтому не буду

Andrey
27.02.2018
17:20:34

Vladimir
27.02.2018
17:20:51

Andrey
27.02.2018
17:21:18

Vladimir
27.02.2018
17:21:37
То есть на x86 на разных ЦПУ может вести себя по разному
И кстати очень интересный вопрос не подберёт ли Гц структуру в первом случае прямо в процессе работы

Zver
27.02.2018
17:23:35

Andrey
27.02.2018
17:23:42

Vladimir
27.02.2018
17:24:07
Когда Гц прошел и получил видение как тред1
А тред2 из кэша цпу получил старый указатель после уже mark фазы гц

Google

Andrey
27.02.2018
17:25:42

Vladimir
27.02.2018
17:26:08
@VesninAndrey одна из проблем атомарности операций что неатомарный store не гарантирует инвалидацию кэша соседних ядер или цпу
Поэтому теоретически может быть ситуация когда в кэше старый указатель
И его получит тред после того как гц прибрал к рукам данные или закончил фазу mark

Andrey
27.02.2018
17:26:53
а, я понял

Vladimir
27.02.2018
17:27:01
Хотя я не очень уверен

Andrey
27.02.2018
17:27:45
Т.е. не было живых горутин, гц пометил указатель, и тут новая горутина получает этот указатель из кеша и кровь кишки паника
прикольно

Vladimir
27.02.2018
17:27:56

Andrey
27.02.2018
17:29:12
Огромное спасибо за дискуссию! Очень познавательно

BlackTrojan
27.02.2018
17:40:23
А может кто-нибудь объяснить мне, тупому, зачем нужно измерять рэйсы (go run —race main.go) и почему плохо, когда находятся эти самые рэйсы?

Andrey
27.02.2018
17:40:57

Andrey
27.02.2018
17:41:10
Первые 5 минут - ответ на ваш вопрос

Vladimir
27.02.2018
17:54:25
Рейсы плохи тем что у тебя после них неопределенное состояние структур данных которые читались или писались одновременно

Aleksandr
27.02.2018
18:50:16
https://github.com/martingallagher/runes/blob/master/tables.go#L34
коллеги, а вот это на стадии компиляции высчитывается?

Oleh
27.02.2018
18:54:32
нет
init запускается при старте програмы

Aleksandr
27.02.2018
18:55:12
вот и я думаю - странная оптимизация

Vladimir
27.02.2018
18:55:45

Google

Aleksandr
27.02.2018
19:00:56
даже больше. валидных 150т

Vladimir
27.02.2018
19:03:49
Зато потом будут флаги по которым в теории быстрее выборка
Но не факт

Slava
27.02.2018
19:08:15
Нормальный звук! http://golangshow.com/episode/2018/02-27-119b/

Aleksandr
27.02.2018
19:08:40

Admin
ERROR: S client not available

Vladimir
27.02.2018
19:10:02

/dev/m
27.02.2018
19:10:09

Aleksandr
27.02.2018
19:12:02

Vladimir
27.02.2018
19:13:11

Aleksandr
27.02.2018
19:14:31
ну да, но сомнительно. лучше скрипт для апдейта прикладывать

Vladimir
27.02.2018
19:15:52
Чем лучше?

Aleksandr
27.02.2018
19:17:08
не нагружаешь рантайм ненужными вычислениями
перегенерить надо раз в год

Vladimir
27.02.2018
19:18:36
Что не так страшно

anthof
27.02.2018
20:59:56
Всем ку. Подскажите какое нибудь хорошее руководство по созданию менеджера сессий? а то я читаю одно, но не все понятно, откуда что берется...

Google

Nik
27.02.2018
21:02:10
Чьи сессии хотя бы

anthof
27.02.2018
21:04:09
для веб приложения, что бы подойти к организации авторизации, я так понимаю, нужно понять как работает сессия и сделать менеджер сесии

Kirill
27.02.2018
21:07:46
всем привет, только вкатываюсь в го, возник вопрос
если json api post ожидает какое то поле int, а поле не приходит
go парсит это поле как 0. Можно как то узнать это в поле пришел ноль, или поле вообще не пришло?
не смог нагуглить(

Mykyta
27.02.2018
21:09:55

Nik
27.02.2018
21:15:04
Вариант 2 - сессия равна куке, и ты хранишь ее в какомнить горячем хранилище, с экспайром

Di0niz
27.02.2018
21:20:28
Прошу подсказать, как можно протестировать main(), чтобы на вход передать строку со значениями (или stream)
//main_test.go
func TestMain(t *testing.T) {
os.Stdin.Write([]byte("333\n"))
main()
}
//main.go
func main() {
var N int
fmt.Scan(&N)
fmt.Println("read: ", N)
}

Kirill
27.02.2018
21:21:34

anthof
27.02.2018
21:23:05

Nik
27.02.2018
21:27:48

anthof
27.02.2018
21:28:51

Nik
27.02.2018
21:29:16
Если после останутся вопросы - заходи еще?

anthof
27.02.2018
21:31:08
Это семейство хранилищ. Лучше сходи погугли
так а поконкретней что лучше выбрать? по описаниям я все равно не пойму что для меня лучше, а постоянно переучиваться или учить все, у меня времени не хватает. По этому нужно что нить одно)

Nik
27.02.2018
21:32:05

anthof
27.02.2018
21:33:54

Nik
27.02.2018
21:34:17