Igor
на первый взгляд тут работа с указателем происходит (возможно даже что он кастится)
Kirill
&
это уже при записи в буфер
Kirill
пиздишь
Kirill
простите - ты неправ
Igor
о спасибо
Igor
как то привык видеть больше & в связке с указателем
Igor
и начал думать в эту сторону
Kirill
unsafe.Pointer + uintptr = что хочешь делай
Kirill
а ты не знал, что и там пиздежа - хоть обмажся?
Kirill
более того, в рантайме - вообще отдельный мир
Kirill
а чуть ниже - &buf
Kirill
там вообще где-то было написано, что нельзя знать где выделится переменная - на стеке или в хипе
Kirill
так вот - можно выделять на стеке
Kirill
а можно в хипе
Kirill
да, но это обычно первый этап)
Anonymous
тут много обсуждали boltdb, а расскажите про него
Doublegrey
тут много обсуждали boltdb, а расскажите про него
Это считай бд, только с самым минимумом возможностей. Тоесть, если например mysql для твоего проекта слишком громоздкая
Doublegrey
Но как я знаю, его создатель уже потерял к проекту интерес
Anonymous
вот к примеру это же встраиваемая бд, такие бд используют вместо серверов-бд в тех же условиях? те поднимают какой-то сервер, который обрабатывает запросы? например есть такой вариант https://github.com/skyec/boltdb-server/blob/master/server.go
Anonymous
или его юзают только когда приложение напрямую лезет в папку/файл, где хранятся данные
Doublegrey
Кстати, важный вопрос от дурачка) почему проверку на ошибку не аыносят в функцию?
Anonymous
Кстати, важный вопрос от дурачка) почему проверку на ошибку не аыносят в функцию?
потому что из вложенной ф-ции ретурн во внешней ф-ции не сделать?
Doublegrey
Можно статью сюда кинуть?
Doublegrey
Связано с программированием, но отдаленно
M
Всем добрый вечер! У меня есть эндпоинт, который принимает POST запросы с определенными данными которые нужно записать в БД. Запросов может быть очень много. Мне нужно ограничить количество принимаемых данных (скажем, до 20) за определенный промежуток времени (1 секунда) чтобы можно было все это записать и не открывать множество соединений в БД. Если я правильно понимаю, то нужно создать 2 горутины - одна будет принимать данные, а вторая считать время. Пытался найти похожее решение в сети, но так не нашел. Наткнулся на тесты в исходниках go, но там ничего похожего нету: https://github.com/golang/go/blob/master/src/database/sql/sql_test.go Я в Go не очень опытен в плане многопоточности, поэтому не обуссудьте за такой вопрос.
M
Буду признателен за любую помощь
Co.In
одна горутина наполняет стек, другая снимает с него и сохраняет в базу, та которая забирает со стека пусть забирает пачки по 20 записей раз в секунду, это и будет вам ограничением. Ну или можете ограничить ту которая складывает в стек количеством, тогда часть данных может потерятся в случае большой нагрузки, ну либо продумать механизм ожидания
Dug
А в go нельзя один раз открыть бд и не закрывать? (Я совсем зеленый в go, если что)
Kirill
А в go нельзя один раз открыть бд и не закрывать? (Я совсем зеленый в go, если что)
замени слово бд на дверь и поймёшь, насколько расплывчатый это вопрос
Dug
Ну парень выше задал вопрос и писал, что решение ему требуется, чтобы по несколько раз не открывать соединение с бд. Вот и спрашиваю)
Vasily
Почти везде коннекшен пул
Vasily
В самом популярном драйвере к Mysql - точно
Vasily
лучше только сразу ограничить количество коннектов к базе
Vasily
ну и можно набирать какое-то количество записей в памяти, а потом бисать в базу сразу пачкой - может быть сильно быстрее
M
Ребят, если вам не сложно, можете кинуть ссылку на похожую проблему? Я либо неправильно ищу, либо это сложно найти
Vasily
на какую именно проблему? как писать в канал и читать из него ?
M
запись в бд с временнным интервалом и определенным количеством данных
Vasily
insert into tableName ( field1, field2) values (1,1), (2,2), (3,3)
Vasily
https://github.com/golang/go/wiki/RateLimiting - простой рейтлимитер но можно обойтись даже стандартным тикером
Co.In
Кто то знает почему "error strings should not be capitalized or end with punctuation" Тоесть чем это чревато? Кроме дурного тона?
aadz
This does not apply to logging, which is implicitly line-oriented and not combined inside other messages.
Doublegrey
А в go нельзя один раз открыть бд и не закрывать? (Я совсем зеленый в go, если что)
Можно. Его обычно дефером закрывают, под конец исполнения программы
Kirill
В самом популярном драйвере к Mysql - точно
Нет там пула, пул "из коробки" идет в самом database/sql и его можно подкрутить под себя (читать отсюда по Set* https://golang.org/pkg/database/sql/#DB.SetConnMaxLifetime). При конкурентном доступе он будет пытаться открыть новое соединение или взять из пула, также при открытии транзакции он закрепляет соединение за стейтментом пока транзакция не закроется, т.е. в разных транзакциях будут разные соединения
Kirill
insert into tableName ( field1, field2) values (1,1), (2,2), (3,3)
И вот так делать тоже зло, лучше делать подготовлнные запрос и потом в цикле лить данные: tx,_:=conn.Begin() stmt,_:=tx.Prepare("INSERT INTO t VALUES (?, ?)") for _, row:=range rows { stmt.Exec(row.V1,row.V2) } tx.Commit()
Kirill
Всем добрый вечер! У меня есть эндпоинт, который принимает POST запросы с определенными данными которые нужно записать в БД. Запросов может быть очень много. Мне нужно ограничить количество принимаемых данных (скажем, до 20) за определенный промежуток времени (1 секунда) чтобы можно было все это записать и не открывать множество соединений в БД. Если я правильно понимаю, то нужно создать 2 горутины - одна будет принимать данные, а вторая считать время. Пытался найти похожее решение в сети, но так не нашел. Наткнулся на тесты в исходниках go, но там ничего похожего нету: https://github.com/golang/go/blob/master/src/database/sql/sql_test.go Я в Go не очень опытен в плане многопоточности, поэтому не обуссудьте за такой вопрос.
Создай канал буферизированный в 1-й горутине пиши туда, в другой читай. Мы так и пишем, только у нас размер не 20 записей, а 100к, для верности у нас есть еще промежуточный буфер чтоб не потерять данные если запись в БД не прошла, т.е. если данные в буфере есть читаем из него, если нет читаем из канала (это если на "пальцах")
nikita
нене, по таймауту вы тоже в базу суете все, что накопилось?
Kirill
100к в одной транзакции?
Да, когда "догоняем" например после рестарта воркера можем и больше писать
Anonymous
Или у вас аппенд онли
Kirill
У нас аппенд онли
Vladimir
Ну у вас и база такая что ей так даже хорошо же)
Kirill
Ага )
Alexey
И вот так делать тоже зло, лучше делать подготовлнные запрос и потом в цикле лить данные: tx,_:=conn.Begin() stmt,_:=tx.Prepare("INSERT INTO t VALUES (?, ?)") for _, row:=range rows { stmt.Exec(row.V1,row.V2) } tx.Commit()
Почему это плохо? Несколько раз прибегал к этому подходу, думал про bulk, но в одном из проектов мы используем mssql, а в стандартном драйвере нет булка ;(
Vsevolod
чем мерил?
бенчами и мелкими проектами.
Dmitry
эх, жаль что только так, я бы почитал бы статью на эту тему
Quet
на удивление, но скорость вставки этого "зла" выше чем у подготовленного запроса.
а почему удивление? ни одной причины почему скорость должна быть ниже
Kirill
на удивление, но скорость вставки этого "зла" выше чем у подготовленного запроса.
это если запрос достаточно маленький, если данных много то вы 1 раз отправляете запрос, сервер его разбирает и строит план запроса, дальше льете только данные. Соответственно если делать много VALUE то вам нужно сразу передать достаточно большой объем данных, а также серверу нужно его попарсить. ну и в подготовленном запросе вы отдельно передаете сам запрос и отдельно данные, т.е. инъекции чуть более чем исключены
Kirill
В этом плане очень интересно сделано в native протоколе ClickHouse, вся работа по разбору запроса ложится на клиент )
Alex
Для го есть какая-нибудь либа для управления системными пользователями и группами? Создать там, удалить, членов группы вывести. Стандртный os/user вообще ничего не умеет.
No1
Конечно нет, этим должны рулить другие инструменты.
aadz
Конечно нет, этим должны рулить другие инструменты.
тут же погромисты собираются. Они имеют обыкновение как раз инструменты сами и писть. :)
Alex
Спасибо!
Alex
я уже такой херни понаписал, лол if _, err := exeCmd("usermod", "-a", "-G", groupName, username); err != nil { return fmt.Errorf("can't add user %v to group %v with: %v", username, groupName, err)