Кириллл
Спасибо
Anonymous
Кто нибудь знает как правильно анмаршалить сообщения protobuf? Везде примеры типа
test := &example.Test{}
data, err := proto.Marshal(test)
newTest := &example.Test{}
err = proto.Unmarshal(data, newTest)
А если у меня открыто tcp соединение в которое я кидаю разные сообщения protobuf, как детектить какое сообщение пришло?
Если в первый байт пакета писать его идентификатор, и на принимающей стороне его считывать
получается что-то типа
switch(recvBytes[0]){
case 0:
msg := &pbMessage1{}
if proto.Unmarshal(recvBytes[1:], msg) != nil{
return
}
case 1:
msg := &pbMessage2{}
if proto.Unmarshal(recvBytes[1:], msg) != nil{
return
}
case 2:
msg := &pbMessage3{}
if proto.Unmarshal(recvBytes[1:], msg) != nil{
return
}
}
Отправка сообщений - аналогичный свич, который пишет в первый байт id пакета
Это просто ужастно, глаза текут от такой фигни
Как сделать по нормальному?
Anonymous
😭😭😭
Aleksandr
протобаф для того и сделан, чтобы не детектить что пришло
Aleksandr
протокол сам все детектит, сгенеренный код сам анмаршаллит
Anonymous
как это сделать
Aleksandr
что?
Anonymous
"анмаршальнуть"
Anonymous
можешь дать пример кода?
Anonymous
пушта метод proto.Unmarshal требует в аргумент тип pb Message
Aleksandr
https://developers.google.com/protocol-buffers/docs/techniques#streaming
Aleksandr
это навреное
Aleksandr
ну и погуглить как это делается
Aleksandr
https://www.google.com/search?client=ubuntu&hs=AZW&channel=fs&biw=1920&bih=926&ei=hD1rW4-yOYTksAeYmLuwBA&q=golang+protobuf+dynamic+messages&oq=golang+protobuf+dynamic+messages&gs_l=psy-ab.3..0i19k1.23620.30384.0.30529.29.21.3.5.6.0.194.2295.12j9.21.0....0...1c.1.64.psy-ab..2.26.2047...0j0i22i30k1j0i13k1j0i13i30k1j0i13i5i30k1.0.udL7uH0hYtI
Anonymous
Aleksandr
я не совсем понял задачу изначально
Daniel
Кто нибудь знает как правильно анмаршалить сообщения protobuf? Везде примеры типа
test := &example.Test{}
data, err := proto.Marshal(test)
newTest := &example.Test{}
err = proto.Unmarshal(data, newTest)
А если у меня открыто tcp соединение в которое я кидаю разные сообщения protobuf, как детектить какое сообщение пришло?
Если в первый байт пакета писать его идентификатор, и на принимающей стороне его считывать
получается что-то типа
switch(recvBytes[0]){
case 0:
msg := &pbMessage1{}
if proto.Unmarshal(recvBytes[1:], msg) != nil{
return
}
case 1:
msg := &pbMessage2{}
if proto.Unmarshal(recvBytes[1:], msg) != nil{
return
}
case 2:
msg := &pbMessage3{}
if proto.Unmarshal(recvBytes[1:], msg) != nil{
return
}
}
Отправка сообщений - аналогичный свич, который пишет в первый байт id пакета
Это просто ужастно, глаза текут от такой фигни
Как сделать по нормальному?
мы тут в личке поговорили, и пришли к выводу, что надо просто взять grpc
Slava
Slava
всё через протобаф, без всяких волшебных байтиков
ThunderAL
как запустить команду и закрыть программу не дожидаясь её завершения?
(я делаю обновление. качаю файл, и запускаю его, а он уже будет делать что надо)
Заур
ThunderAL
не, screen и jobs, это, конечно, святое, но как это сделать силами golang?
Aleksandr
но зачем?
Wingman
Заур
Wingman
но зачем?
Меня тоже вымораживает невозможность штатно daemonize'иться (
Aleksandr
в линуксе есть systemd и иже с ним.
Заур
Заур
Есть готовые либы
Nik
а че, нельзя сделать exec.Command("nohup", "./mycoolapp&") и потом застрелиться? Мимокродил
ThunderAL
да помню, что в java и в дельфях я обновления пилил так:
качаем файл, запускаем и сразу завершаем данный процесс, а программа обновления распаковывает с заменой файлов и снова запускает мою программу
ThunderAL
как раз и хочу вывернуться так, чтобы запустить обновлялку и дать ей возможность перезаписать файл, из которого она была запущена
Заур
+ к вопросу, как это делается?
Мне кажется текущий вариант немного неправильный, потому что в случае ошибки и старый завершится и новый не будет запущен.
Aleksandr
у телеграма на десктопе например отдельный апдейтер
German
Всем доброго дня,
кто-нибудь пользует в проде /valyala/fasthttp? Сильно ли он лучше нынешней стандартной либы?
Vadim
Kirill
Всё работает шустрее и очевиднее
German
Maxim
Alexandr
Здравствуйте! слайс на 200к записей вида []struct{uint64, int} это норм, чтоб из базы выбирать столько за раз?
Alexandr
или лучше частями?
Daniel
можно и разом. это же в районе двух мегабайт всего данных
Anonymous
Коллеги, как правильно сделать нормальные логи в приложении? Если мы будем прокидывать эррор постоянно наверх, то мы при записи получим только само сообщение об ошибке и номер строки, где логгирование случилось, а не гле именно произошла ошибка.
V
залогировать ошибку перед возвратом?
Anonymous
V
чтобы вызывающая функцию логика корректно отработала?
Maxim
Maxim
Мы не экстрасенсы и однозначно утверждать что надо, а что не обязательно писать мы не можем
V
A вызывает B, B генерирует ошибку errB, логирует и возвращает. A обрабатывает ошибку и, если надо, генерирует ошибку errA, логирует и возвращает. Как-то так?
arkady
парни, а будет ли гонка если две горутины будут читать из одной мапы?
.
.
Если еще и пишет кто-то в эту мапу
arkady
у меня по дизайну пишет только одна горутина
Anonymous
Про какую функцию сейчас идёт речь?
Есть исполняемая функция. в ней происходит ошибка. Функция имеет примерно такую сигнатуру:
func myname1 (...) error {...}
Если там срабатывает ошибка, то она получается что прокидывает её наверх в вызывающую функцию (а та, возможно, ещё выше) до того места, пока всё это не попадёт в конечную функцию (например в main) где логируется возврат ошибки самой верхней вызывающей функции. В этом случае, не понятно, откуда именно пришла ошибки, т.к. мы получаем текст ошибки и номер строки ошибки в main.
Однако, если мы будем логировать ошибку в самой функции myname1 где она и происходит, то нафига нам вообще нужно эту ошибку прокидывать наверх? сделаем чтобы она не возвращала ошибку и всё.
.
Если есть запись, тут уже точно надо мьютекс юзать
Anonymous
V
нет
Anonymous
тогда непонял
V
errA может быть агрегирующей для других вызовов
Anonymous
Есть исполняемая функция. в ней происходит ошибка. Функция имеет примерно такую сигнатуру:
func myname1 (...) error {...}
Если там срабатывает ошибка, то она получается что прокидывает её наверх в вызывающую функцию (а та, возможно, ещё выше) до того места, пока всё это не попадёт в конечную функцию (например в main) где логируется возврат ошибки самой верхней вызывающей функции. В этом случае, не понятно, откуда именно пришла ошибки, т.к. мы получаем текст ошибки и номер строки ошибки в main.
Однако, если мы будем логировать ошибку в самой функции myname1 где она и происходит, то нафига нам вообще нужно эту ошибку прокидывать наверх? сделаем чтобы она не возвращала ошибку и всё.
если выкинул ошибку выше, то логировать не надо
Maxim
Есть исполняемая функция. в ней происходит ошибка. Функция имеет примерно такую сигнатуру:
func myname1 (...) error {...}
Если там срабатывает ошибка, то она получается что прокидывает её наверх в вызывающую функцию (а та, возможно, ещё выше) до того места, пока всё это не попадёт в конечную функцию (например в main) где логируется возврат ошибки самой верхней вызывающей функции. В этом случае, не понятно, откуда именно пришла ошибки, т.к. мы получаем текст ошибки и номер строки ошибки в main.
Однако, если мы будем логировать ошибку в самой функции myname1 где она и происходит, то нафига нам вообще нужно эту ошибку прокидывать наверх? сделаем чтобы она не возвращала ошибку и всё.
Всё зависит от формата логгирования. Можно писать лог в корне, а возвращать оформленную подобающим образом ошибку из недр
Anonymous
логируй на уровень выше
Maxim
Можно писать лог чуть ли не в каждом кейсе if err != nil, тут как удобнее
Daniel
Есть исполняемая функция. в ней происходит ошибка. Функция имеет примерно такую сигнатуру:
func myname1 (...) error {...}
Если там срабатывает ошибка, то она получается что прокидывает её наверх в вызывающую функцию (а та, возможно, ещё выше) до того места, пока всё это не попадёт в конечную функцию (например в main) где логируется возврат ошибки самой верхней вызывающей функции. В этом случае, не понятно, откуда именно пришла ошибки, т.к. мы получаем текст ошибки и номер строки ошибки в main.
Однако, если мы будем логировать ошибку в самой функции myname1 где она и происходит, то нафига нам вообще нужно эту ошибку прокидывать наверх? сделаем чтобы она не возвращала ошибку и всё.
под такие случаи существуют такие пакеты и функции: https://godoc.org/github.com/powerman/structlog#Logger.Err
и логирует, и возвращает.
Alexander
@alexsafronov а это библиотека или конечное приложение ?
Anonymous
Daniel
на каждом
Anonymous
Anonymous
все зависит от логики,если ошибка не фатальная и дальше не кидается, то логируй
Anonymous
а если она сразу делает return, то лучше логировать еще выше
Anonymous
Anonymous
Anonymous
если ты после ошибки продолжаешь что-то делать в этой функции
V
если сервис А вызывает сервис В, который вызывает сервис С, где происходит ошибка, то сервис А не очень ожидает увидеть ошибку сервиса С