3030
Коллеги, подскажите пожалуйста. Есть канал, туда идет запись. Нужно читать из этого канала в буффер и по заполнению буфера, либо достижению какого-то таймаута скидывать из этого буфера в базу. Сейчас это делается через case <-time.After(5 * time.Second) (https://gist.github.com/anonymous/2311adbd6fd3316c2643cd0228ededc0) Проблема в том, что этот таймаут "отсчитывается" от момента последнего чтения из канала. и если в канал идет запись, скажем, каждую секунду, а размер буфера, например, 1000, то через желаемые 5 секунд "сброса" в базу не произойдет. Он будет только, если эти 5 секунд вообще не будет ничего из канала приходить. Как реализовать желаемое?
3030
идея ясна, уже как раз в эту сторону начал эксперементировать
3030
спасибо!
heavycharged
читать из <-time.After(), это вообще законно? он же bool возращает.
Andrey
он Time возвращает
heavycharged
а, да, гоню.
heavycharged
кстати, лучше на NewTicker переделать.
Andrey
Ну, и это же канал. Он и создан чтобы из него читать
Andrey
кстати, лучше на NewTicker переделать.
а что из таймеров можно сбрасывать, чтобы отсчет заново пошел?
heavycharged
func (t Time) After(u Time) bool я сюда глянул сначала
heavycharged
на NewTicker там из-за утечки.
heavycharged
The underlying Timer is not recovered by the garbage collector until the timer fires. If efficiency is a concern, use NewTimer instead and call Timer.Stop if the timer is no longer needed.
3030
да, тикер выглядит более правильным
heavycharged
там нужно в условии написать, по заполнению буфера дернуть ticker.Close()
3030
попробую
3030
А вот насколько в таком случае плохо использовать для буфера слайсы и каждый раз после flush'а создавать новый слайс? Можно же создать слайс известной длины (массив?) и писать/сбрасывать в/из него? тогда на каждой итерации не будет лишнего выделения памяти (и потом чистки) - верно понимаю?
Andrey
Верно
3030
спасибо
🎉
Я вот чото не пойму, вот образец простого веб-сервера. package main import ( "fmt" "http" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "Привет %s!", r.URL.Path[1:]) } func main() { http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil) } Но вот не вижу здесь многопоточности, она под капотом? Или как это вообще работает?
Aleksandr
на каждый реквест открывается отдельная горутина
heavycharged
да, под капотом :)
🎉
А, всё понятно теперь, спасибо.
heavycharged
bytes.Buffer может как-то вычитать всю строку, если он уже проинициализирован, без создания strings.NewReader?
heavycharged
методы посомтрел у буфера?
метода нет, а вообще вызов strings.NewReader выделяет какую-то память или нет, он же вроде строку копирует - а значит выделяет? я использую буфферы для построения SQL запросов, и там в некоторых случаях делается запись в буфер разных ORDER BY LIMIT и прочего, после чего вызываю buffer.String() и передаю параметры в запрос. Ко всему этому я прикрутил sync.Pool, чтобы буферы из пула брать а не создавать постоянно. Вот собственно возник вопрос, я тут выиграю в производительности, или нет?
heavycharged
один отпал, но есть ещё несколько
Vitaly
А кто-нибудь юзает gobuffalo.io ? Тут вроде и миграции и фронт есть.
🎉
А кто-нибудь юзает gobuffalo.io ? Тут вроде и миграции и фронт есть.
Неплохо. Как только люди умудряются такие объёмы писать.
🎉
один сплошной враппер
Я в терминах не силён)) Что такое враппер?
heavycharged
Я в терминах не силён)) Что такое враппер?
враппер - функция-обертка над другой, более низкоуровневой функцией. buffalo беглым взглядом глянул, они взяли кучу пакетов, объединили и написали врапперы, для удобства.
🎉
А, ну они вроде позиционируют это не как фреймворк, а как эко систему, для разрабов.
Vitaly
Нарыл недавнишний обзор buffalo - выглядит очень удобным https://www.youtube.com/watch?v=J0JnHNgPMRk
🎉
Чото упарился, никак не могу придумать как обойти ошибку. sql: Scan error on column index 3: converting driver.Value type <nil> ("<nil>") to a int64: invalid syntax
Vasily
golang sql null handling
🎉
Да вроде как почитал, поменял в структуре на sql.NullInt64 и sql.NullString. Не помогает, что-то видимо не так делаю.
Stanislav
помогает, сам пользую
Заур
народ, вот такая проблема при сравенении l.ch == '\n' выдаёт false, хотя l.ch руна и содержит символ \n. проверял, у обоих код 10
Заур
в чём может быть причина?
Заур
ой, всё, пардон))
Oleh
мне нужно сделать прокси, который будет пересылать через другой прокси (разпределять данные между ними) посоветуйте пожалуйста как лутше сделать?
Oleh
пробовал https://github.com/elazarl/goproxy но что то не могу норм конект к проксе настроить
Oleh
к той другой, куда нужно проксировать
🎉
sql.NullInt64
Да я тоже прописал, не пойму как ошибку отловить. Может что не так пишу? Можно на образец взглянуть?
🎉
type DATA struct { ID int64 ChatID sql.NullInt64 Balance sql.NullInt64 MessageID int StateWhat sql.NullString PathWhere sql.NullString DateTime *time.Time } Читаю из базы func ReturnUser(db *sql.DB, ChatID int64) (p *DATA, err error) {} Если пользователя нет, пишу в неё. p := new(DATA) p.ChatID.Int64 = ChatID p.MessageID = MessageID p.StateWhat.String = "start" p.PathWhere.String = "main" InsertUser(db, p) func InsertUser(db *sql.DB, p *DATA) (lastID int64, err error) {} С первого подключения, я не вижу пользователя в базе, и прописываю его туда. Но так как Balance, в структуре я не заполнил, то в базу пишется nil(я так думаю). Затем, очищаю историю(это бот), и снова жму старт. Тут бот падает с этой ошибкой.
🎉
То есть он пытаясь читать юзера из базы встречает nil.
Stanislav
В nullint64 есть еще параметр Valid
Stanislav
Как и у всех null*
🎉
В nullint64 есть еще параметр Valid
То есть, это нужно как-то указывать, при чтении/записи?
Andrey
Покажите сам запрос
Andrey
В смысле как делаете rows.Scan
🎉
func ReturnUser(db *sql.DB, ChatID int64) (p *DATA, err error) { p = new(DATA) err = db.QueryRow("SELECT * FROM data WHERE ChatID=?", ChatID).Scan(&p.ChatID, &p.Balance, &p.MessageID, &p.StateWhat, &p.PathWhere) return p, err } Вот так, потом я его ещё проверяю. if err != nil { if err == sql.ErrNoRows { // Если строки нет, то пишу в базу } log.Fatal(err) }
Andrey
а MessageID у вас 100% не nil?
Andrey
Сделайте его тоже sql.NullInt64 просто ради интереса
🎉
а MessageID у вас 100% не nil?
Ну да, не nil. Balance 100% nil. Я часть убрал для простоты.
🎉
Сделайте его тоже sql.NullInt64 просто ради интереса
Так не получится, ибо он в либе прописан как int.
Andrey
Ну, подставьте в скан локальную переменную для теста
🎉
У вас в ошибке просто говорится, что именно третий параметр не заходит
Ну да, это Balance, говорю же убрал лишнее, поэтому показывает на MessageID.
Andrey
😂
Andrey
Так, ладно)
🎉
Залочить структуру нуно?
Andrey
Вам компилятор сообщает где у вас ошибка
Anonymous
Мне нужен код без вашего "упрощения"
Проще сделать unique index и сразу делать insert)
Andrey
Проще сделать unique index и сразу делать insert)
Не проще) Это лишний запрос к базе. Его можно избежать. Но это совсем другая история.
Andrey
С чего эт? Эт один запрос
Ни одного запроса - лучше чем один