Zver
Если да, то дописывайте теги и рефлексируйте структуру и никаких проблем. По другому сначала передаете записывателю слайс с заголовками, а потом просто мапу со значением колонок.
Zver
Я бы взял структуру, если она всегда известна. type Parampampam struct { Name string csv:"Name" } Что-то в этом роде
Zver
Можно даже тогда заголовок не инициализировать отдельно, если первая запись, то сначала выводим заголовок, а потом данные.
heavycharged
структура всегда известна (я её смотрю перед началом работы), но каждый раз разная со своим геморроем)) часто работаю с интернет-магазинами, помогаю миграции делать и прочее, и, сцуко, ни один поставщик не следуют строгому формату, тому же yml например. постоянно приходится писать транспорты, которые где-то на миллиметр, но отличаются, и вот думаю уже который раз сделать какое-то гибкое решение, которое позволит сэкономить мне время на описании алгоритмов конвертации. где-то у файла есть header, где-то нет. где-то в csv нужно очередность сохранить, и указывать после товара строку с артикулом, но без product_id. Вот собственно думал как-бы покрыть хотя бы часть таких конвертаций, но видимо чудес не бывает.
Zver
структура всегда известна (я её смотрю перед началом работы), но каждый раз разная со своим геморроем)) часто работаю с интернет-магазинами, помогаю миграции делать и прочее, и, сцуко, ни один поставщик не следуют строгому формату, тому же yml например. постоянно приходится писать транспорты, которые где-то на миллиметр, но отличаются, и вот думаю уже который раз сделать какое-то гибкое решение, которое позволит сэкономить мне время на описании алгоритмов конвертации. где-то у файла есть header, где-то нет. где-то в csv нужно очередность сохранить, и указывать после товара строку с артикулом, но без product_id. Вот собственно думал как-бы покрыть хотя бы часть таких конвертаций, но видимо чудес не бывает.
Записывайте просто на основании структуры с полями, в тегах указывать необходимое наименование. Можете еще функциию передовать для преобразования полей. func Write(data interface{}, convert func(field string, value interface{}) value interface{}) err Если нужны сложные преобразования, то делать их вне записи. Сначала прочитать, потом конвертировать в нужную структуру данных, а потом уже как обычно вывести.
Zver
Писатель все же должен заниматься писанием, а не преобразованием. Иначе это бeдет выглядеть более монструозно, чем конвертер посередине.
heavycharged
да. я тоже так думаю, но пока делаю просто наброски, прощупываю возможность и ищу лучшую реализацию. спасибо всем за советы.
🍗
интересно было взглянуть на эмулятор сервера какой-то игры на Go, кто-то такое видел ибо всё на java и на java)
freezlite
прям таки все на java ?
🍗
Подавляющее большинство)
.
Возникла проблема с драйвером под Postgres (pq). При возрастающем количестве соединений к серверу (> 125) начинают лезть ошибки pq: remaining connection slots are reserved for non-replication superuser connections и pq: sorry, too many clients already. С чем может быть связано и как это решить?
Aleksandr
не закрываешь соедеинения
.
Окей, как это сделать? У меня в main() открывается соединение с помощью sql.Open(), потом я в хендлеры API вызовов передаю указатель на БД *sql.DB, где уже выполняются запросы к БД. Где что мне надо закрывать?
Aleksandr
закрывай Rows
Aleksandr
в основном там теряются соединения
.
у меня в вызове есть только QueryRow
Aleksandr
один запрос на все приложение?
.
нет нет
.
в функции, которая передается хендлеру, делается запрос к БД с помощью QueryRow()
Aleksandr
ну а QueryRows например у тебя нигде нет?
.
в драйвере под монгу mgo как я помню соединения пихаются в пул и проблем так вообще не было. а вот с postgres появились
Aleksandr
здесь тоже в пуле
Aleksandr
и на всех sql-драйверах эта проблема
.
А нет, сейчас проверю на счет QueryRows, мне кажется все таки есть вызов
Aleksandr
в функции, которая передается хендлеру, делается запрос к БД с помощью QueryRow()
а когда передаешь в хэндлер QueryRow, всегда потом сканируешь его? или при наступлении условия?
.
Я в хендер передаю только указатель на БД. В функции уже делаются запросы к БД. Сканируются всегда
.
сделал rows.Close(), 0 эффекта
Aleksandr
в общем посмотри свои запросы. каждый запрос создает подключение к базу - его надо закрыть, иначе кончатся. в QueryRow например подключение закрывается автоматически во время скана. в QueryRows не закрывается.
.
Ошибки лезут даже когда делается чисто один QueryRow. Мда
Aleksandr
тогда много одновременных соединений
Aleksandr
https://stackoverflow.com/questions/2757549/org-postgresql-util-psqlexception-fatal-sorry-too-many-clients-already
.
На самом деле это как то странно
.
Вот опять же, с MongoDB было все ок даже при большом количестве соединений. Вообще монга не показывал более 10 открытых соединений.
.
А тут Пострес требует настроек для того чтобы обрабатывать более 100 соединений
heavycharged
func (db *DB) SetMaxIdleConns(n int) func (db *DB) SetMaxOpenConns(n int)
Wingman
пушто особенности
Wingman
в pg соединения - дороги
Wingman
и вообще желательно юзать pgbouncer
heavycharged
попробуй прописать SetMaxIdleConns 10 и например MaxOpenConns 50
Wingman
или поюзай go-pg и модели мне пока нравится
Petr
mysql+postgre+oracle все они требуют настроек для коннектов, на продакшене от этого одни плюсы
Wingman
пг вообще по дефолту настроен так, чтобы на любом утюге запустился
.
Он то запустился, но требует много настроек
Wingman
уточняю: он по дефолту настроен с самым-самым-самым минимальным потреблением всего, чего только можно)
heavycharged
Он то запустился, но требует много настроек
SetMaxIdleConns и SetMaxOpenConns попробуй. Это не много.
.
Окей, попробую
heavycharged
я по дефолту и для MySQL так указываю. все коннекты нужно контролить.
.
В общем проблема решилась (я надеюсь) установкой следующих параметров dbConnection.SetConnMaxLifetime(5 * time.Minute) dbConnection.SetMaxOpenConns(5) dbConnection.SetMaxIdleConns(0) Но я реально не понял ПОЧЕМУ это решило проблему. Кто нибудь может обьяснить? 😂
.
Например, если увеличить макс кол-во открытых соединений, то проблема возвращается
.
Как это работает вообще
Kirill
Видимо ты где-то не закрываешь подключения, и выставив lifetime, ты стал их закрывать
Kirill
Остаётся только один вопрос
Kirill
Насколько это хорошее решение
.
Lifetime роли не играет
.
Я проверил
.
Если его убрать или увеличить, все также ок
G72K
и вообще желательно юзать pgbouncer
С ним , кажется, потеряете prepared statements, а они скорости помогают неплохо
.
С ним , кажется, потеряете prepared statements, а они скорости помогают неплохо
Вроде как Prepared Statements в Го работают не так, как ожидается, и для каждого запроса создаётся новое соединение
.
Но я могу ошибаться
Aleksey
Но я могу ошибаться
Нормально работают подготовленные запросы.
Aleksey
Подготовленные запросы не нужно наготавливать для использования на протяжении всей программы. Их нужно использовать, например, в циклах, чтобы сиквел сервер один раз интерпретировал запрос, создал план выполнения себе и т.п. а далее получая данные только выполнял заготовленное.
Wingman
Насколько правильно хранить объекты (персистентно хранящиеся в бд) и работать с ними - в памяти, в бд только записывая обновления? Суть: куча объектов (оборудования), постоянно опрашивающегося на предмет кучи параметров. Это уже куча постоянных одинаковых запросов (на один объект - от пары десятков до сотен дочерних объектов) - но это хрен с ним, достаточно безболезненно для бд. Еще это оборудование будет слать логи на сислог и снмп-трапы; какие-то события на оборудовании происходят постоянно, сейчас по нескольку сотен в секунду прилетает - и вот это уже похоже на бессмысленное дрочево БД: гораздо продуктивные было бы держать все в памяти Сейчас еще в голову пришел вариант - простая обёртка над бд, кеширующая в памяти на энное время именно результат запросов (с ключем = мд5 строки запроса, например) Кто как похожие кейсы решает?
Maxim
Насколько правильно хранить объекты (персистентно хранящиеся в бд) и работать с ними - в памяти, в бд только записывая обновления? Суть: куча объектов (оборудования), постоянно опрашивающегося на предмет кучи параметров. Это уже куча постоянных одинаковых запросов (на один объект - от пары десятков до сотен дочерних объектов) - но это хрен с ним, достаточно безболезненно для бд. Еще это оборудование будет слать логи на сислог и снмп-трапы; какие-то события на оборудовании происходят постоянно, сейчас по нескольку сотен в секунду прилетает - и вот это уже похоже на бессмысленное дрочево БД: гораздо продуктивные было бы держать все в памяти Сейчас еще в голову пришел вариант - простая обёртка над бд, кеширующая в памяти на энное время именно результат запросов (с ключем = мд5 строки запроса, например) Кто как похожие кейсы решает?
Самое простое закешировать в редисе.
Zver
Насколько правильно хранить объекты (персистентно хранящиеся в бд) и работать с ними - в памяти, в бд только записывая обновления? Суть: куча объектов (оборудования), постоянно опрашивающегося на предмет кучи параметров. Это уже куча постоянных одинаковых запросов (на один объект - от пары десятков до сотен дочерних объектов) - но это хрен с ним, достаточно безболезненно для бд. Еще это оборудование будет слать логи на сислог и снмп-трапы; какие-то события на оборудовании происходят постоянно, сейчас по нескольку сотен в секунду прилетает - и вот это уже похоже на бессмысленное дрочево БД: гораздо продуктивные было бы держать все в памяти Сейчас еще в голову пришел вариант - простая обёртка над бд, кеширующая в памяти на энное время именно результат запросов (с ключем = мд5 строки запроса, например) Кто как похожие кейсы решает?
Если вы у бд один клиент, то вполне нормально. Это фактически и получается кэш. Хэш может давать коллизию и надо будет сравнивать запросы в любом случае. Можно мапу использовать или key/value хранилище.
Maxim
Насколько правильно хранить объекты (персистентно хранящиеся в бд) и работать с ними - в памяти, в бд только записывая обновления? Суть: куча объектов (оборудования), постоянно опрашивающегося на предмет кучи параметров. Это уже куча постоянных одинаковых запросов (на один объект - от пары десятков до сотен дочерних объектов) - но это хрен с ним, достаточно безболезненно для бд. Еще это оборудование будет слать логи на сислог и снмп-трапы; какие-то события на оборудовании происходят постоянно, сейчас по нескольку сотен в секунду прилетает - и вот это уже похоже на бессмысленное дрочево БД: гораздо продуктивные было бы держать все в памяти Сейчас еще в голову пришел вариант - простая обёртка над бд, кеширующая в памяти на энное время именно результат запросов (с ключем = мд5 строки запроса, например) Кто как похожие кейсы решает?
А если по умному то делать unity of work
Wingman
Самое простое закешировать в редисе.
Лишняя прослойка получается
Maxim
Лишняя прослойка получается
В случае если у вас одно приложение. Но такое редко бывает. Вы же будете масштабироваться) Общий кеш на шаренной памяти же не будете делать)
Maxim
Насчет редко загнул наверно
Daniel
Но и рсубд + кеш та еще мудянка
Daniel
Оо почему?)
Или кеш работает синхронно с базой, и запись идет с ее скоростью
Daniel
Или ты не знаешь, все ли записалось
Wingman
Оо почему?)
От целей зависит Например, прилетает мне лог от неизвестно кого Смотрю в кеш: нет такого устройства, лезу в бд - там его тоже нет, дропаю Если таких пакетов от неизвестных источников будет много - от кеша толку ноль
Wingman
Т.е. в моем случае надо иметь однозначный список объектов либо в бд, либо еще где
Maxim
Рассчитываю все, что нужно любым другим потребителям, отдавать по апи
Мы не много о разном говорим, источник данных один. А приложений которые предоставляет апи может быть много отдельных. Например сервера в разных стойках для резервации. 3 бд инстанса мастер слейв для чтения + слейв без лага для того чтобы в критичной ситуации стать мастером. Плюс три application сервера(контейнера) чтобы при падении хоста у вас ничего не упало. В таком случае кешировать в памяти приложения не получится. Нужен общедоступный кеш)