Alexander
ищи как в маке переменные окружения на постоянку прописывать
MrS
Спс
Sergey
Всем привет!
Такая ситуация: получаю метаданные по GRPC, затем надо эти данные пробросить в бизнес-логику. Как лучше сделать?
- вытащить данные на уровне транспорта и передавать, как аргументы в методы (по идее избыточно, т.к. контекст и так всегда передается первым аргументом);
- вытаскивать данные из контекста через пакет metadata там, где они нужны;
- сделать derived контекст с WithValue, чтобы не таскать в бизнес-логику зависимости в виде пакета metadata;
- другой вариант.
Есть ли какие-то best practices на этот счет?
Maxim
Sergey
thnx
Anonymous
Всем привет! Кто нибудь знает как подружить BindQuery в джин с URLSearchParameters в js чтоб нормально парсило слайс, сейчас отправляю так ?test=t1,t2,t3, а в го вот это как одна строка считывается.
Alexander
Не знаю как в джине, но канонично массивы так в query оформлять ?test[]=1&test[]=2&test[]=3
Alexander
Может джин распарсит такое как слайс
Anonymous
Хотелось бы чтоб сама бинд функция все делала.
Сейчас попробывал ?test[]=t1&test[]=t2&test[]=t3 все считал в слайс как надо, но URLSearchParameters так не умеет вот и думаю как можно сделать чтоб с зяпятыми работало или как urlsearchparameters кастомизировать.
Anonymous
Ну я туда подал объект с массивом и текстовым полем, получил результат с запятыми
let data = {
test: [
"t1",
"t2",
"t3"
],
text: "test-text"
}
Anonymous
new URLSearchParams(data).toString()
Алексей
Коллеги подскажите почему так происходит. Решил сделать флаг, для файла логов и столкнулся с тем, что при --help у меня крашится программа, не могу понять в чём проблема.
package main
import (
"flag"
"fmt"
"log"
"os"
)
type errorsFileFlag struct{ os.File }
func (f *errorsFileFlag) String() string {
fmt.Println("String", *f)
return f.Name()
}
func (f *errorsFileFlag) Set(s string) error {
fmt.Println("Set", *f)
if logFile, err := os.OpenFile(s, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644); err != nil {
return fmt.Errorf("open file %q: %v", s, err)
} else {
f.File = *logFile
return nil
}
}
func ErrorsFileFlag(name string, value *os.File, usage string) *os.File {
fmt.Println("ErrorsFileFlag Func")
f := errorsFileFlag{*value}
flag.CommandLine.Var(&f, name, usage)
return &f.File
}
var errorsFileName = ErrorsFileFlag("e", os.Stderr, "Path to errors file")
func main() {
fmt.Println("before flag parse")
flag.Parse()
fmt.Println("after flag parse")
fmt.Println("MAIN", errorsFileName.Name())
errorLogger := log.New(errorsFileName, "", log.LstdFlags)
errorLogger.Println("test")
}
Alexander
просто так крашится и ни одной ошибки не выдает?
Алексей
Вообщем разобрался
Алексей
https://pkg.go.dev/flag#Value
Алексей
The flag package may call the String method with a zero-valued receiver, such as a nil pointer.
Алексей
package main
import (
"flag"
"fmt"
"log"
"os"
)
type errorsFileFlag struct{ *os.File }
func (f *errorsFileFlag) String() string {
if f.File != nil {
return f.File.Name()
} else {
return ""
}
}
func (f *errorsFileFlag) Set(s string) error {
if logFile, err := os.OpenFile(s, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644); err != nil {
return fmt.Errorf("open file %q: %v", s, err)
} else {
*f.File = *logFile
return nil
}
}
func ErrorsFileFlag(name string, value *os.File, usage string) *os.File {
f := errorsFileFlag{value}
flag.CommandLine.Var(&f, name, usage)
return f.File
}
var errorsFileName = ErrorsFileFlag("e", os.Stderr, "Path to errors file")
func main() {
flag.Parse()
errorLogger := log.New(errorsFileName, "", log.LstdFlags)
errorLogger.Println("test")
}
Alexander
а почему ты так странно пользуешься пакетом flag? обычно объявляют флаги, flag.Parse и уже потом передают результаты куда надо
Alexander
мне как-то лень разбираться в том, что твой код делает. как вижу остальным тоже. но ты, имхо, очень странно пользуешься этим пакетом. к несчастью он имеет недостаток в виде возможности пользоваться статически, но так делать не стоит. в одном месте ты объявляешь флаги, парсишь и потом пользуешься результатом, как параметрами для чего-то там дальше
Alexander
поищи примеры использования flag - быстро найдешь и поймешь все
Alexander
сори, кажется понял, что ты пытаешься сделать. мозг не тригерит слово new в названии ErrorsFileFlag
Алексей
Алексей
Я просто честно говоря не знаю другого способа объявления кастомных флагов с помощью стандартного пакета)
Alexander
я бы просто объявил обычный стринговый флаг, и если он пустой вместо создания файла передал бы os.StdErr
Alexander
ты указываешь на указатель
Alexander
у тебя тип будет не *int, а **int
Alexander
Всем привет, нужен совет
У меня есть небольшие "сессии" юзеров (по 10-15 минут) во время которых сыпятся ивенты в сервис, мне нужно их накопить и при дисконнекте юзера засунуть все накопленные ивенты юзера в clickhouse
Что можно взять под быстрый сторадж ивентов перед батч инзертом в кликхаус?
Думаю просто в map по айди юзера записывать массив обьектов (пейлоад ивентов), но может тут что-то другое нужно юзать
Важна скорость записи, тк ивентов много будет
Alexander
а нельзя раз в n секунд или когда строк со всех юзеров накопилось больше m писать?
Alexander
реально есть потребность строго по юзеру все, что есть писать и нельзя подождать лишние секунды?
Maks
Alexander
опять же если юзеров тысяча в секунду выходит, а строк они по 100 сбрасывают, то кликхаусу будет больно
Maks
Почему не взять инмеморибд какой нить.
Maks
Для хранения
Alexander
зачем?
Alexander
У меня NATS, но персистенс нужен только по одному сабжекту
Юзеров не будем много, максимум 20 в час
Alexander
Пейлоад по каждому ивенту в любом случае должен быть записан в кликхаус, но по одному вставлять это не про эту дб)
Alexander
ну если у тебя за минуту накопилась одна запись и ты вставляешь раз в минуту, то что страшного?
Alexander
опять же перед гошным инсертером можно еще буферную таблицу воткнуть
Alexander
Записей будет около 60 в сек
Maks
Ну да, если у тебя мало ивентов то можешь класс сделать в который ты просто отсылаешь ивенты через пуш, а пуш проверяет сколько накопилось и отправляет в кликхаус очищая очередь
Maks
А как ты понимаешь что юзер вышел? Сессии они сокетные?
Alexander
Alexander
ну окей, чем тебе схема не нравится:
1. Заводишь слайс.
2. Пишешь туда по всем юзерам.
3. Сбрасываешь накопив n строк или спустя m секунд (что раньше)
4. Дополнительно еще можно пытаться прочитать из канала, куда будут писать выходящие юзеры. сигналить, что вышли и нужно их данные сбросить (сбросятся конечно все, которые были в слайсе)
Maks
Ну просто когда там не соккет то тебе нет гарантии такого сообщения. Только по таймауту
Alexander
что плохого в схеме?
Maks
Alexander
накуя?
Alexander
)
Maks
Что бы можно было скинуть только одного пользователя
Maks
Из стека
Alexander
зачем?
Maks
Ну мало ли)
Alexander
почему не скинуть и данные других*
Alexander
?:
Maks
Зависит от задачи)
Alexander
а если сервер упадет?
Alexander
ну ок, мапа слайсов)
Alexander
Всем спасибо, просто хотел чекнуть что в правильном направлении думаю
Alexander
подожди, а зачем мапа? просто слайс, каждый юзер пишет и все по концу свой слайс
Alexander
ну то есть, драйве бд у нас уже сам разруливает конкурентность и контроль ресурсов
Иван Иванович
Указатель не может ссылаться. Он указывает. Ссылается ссылка.
Иван Иванович
Это фактически стандарт для сбора информации о состоянии программ. Тебе пока не надо.
Anonymous
тут есть любители плюсов?
Anonymous
@reijo1337
Anonymous
ты же на плюсах пишешь, верно?
Anonymous
как тебе?
Anonymous
гит чекал
Anonymous
почему перестал?
Иван Иванович
Го -- это С++ здорового человека.
Alexander
go не С++ ни в каком варианте
@name_666
@maks_vesnin, добрый вечер. Как успехи с озоном. Я про их задания с cup mail
Maks
ну мне некогда было решать. Я решил 2 задачи, но во второй тайм лимит вылетел
Maks
я вот щас фикс делаю
@name_666
Оке.
Maks
я сделал Поиск n-го самого большого числа в массиве
и склад
@name_666
А погодите. Вы про общие?