Mike
случайное совпадение названия типов не имеет никакого отношения спецификации одного языка к спецификации другого
Сережа
это спецификация представления чисел с плавающей точкой в памяти компьютера
Сережа
я статью на хабре видел хорошую, сейчас поищу
Сережа
https://habrahabr.ru/post/112953/
Alexey
Написал бота который транслирует в телеграм лог коммитов проектов с Github/Gitlab.
Alexey
Alexey
Буду благодарен, если у вас найдется время и сможете сделать ревью кода. https://github.com/targence/commits-telegram-bot
Alexey
Буду благодарен, если у вас найдется время и сможете сделать ревью кода. https://github.com/targence/commits-telegram-bot
основной код в файле commits.go Вот прежде всего что меня интересует: — глобальные переменные, правильно ли я поступил вынеся var bot *tgbotapi.BotAPI неред c main(), сделав bot доступным во всех функциях — файловая структура проекта, правильно ли я разбил код по файлам — как лучше запускать и билдить проекты: go run commits.go types.go github.go gitlab.go выглят как-то каряво... и такая же команда по build... — commits.go слушает входящие реквесты от gitlab http.HandleFunc("/gitlab", gitlabHandler), но прийти на этот индпоинт может все что угодно. Какой нибудь спам и пр.. Как обрабатывать такие ошибки? Просто возвращать return c каким-то ответом сервера, если не распарсим json? или как-то по другому обычно поступают? decoder := json.NewDecoder(req.Body) var api gitlab err := decoder.Decode(&api) if err != nil { panic(err) }
Oleg
> как лучше запускать и билдить проекты Команда go build (без аргументов) в папке пакета main собирает пакет целиком и кладет бинарник рядом. Не нужно перечислять файлы, это коряво, да :) > прийти на этот индпоинт может все что угодно И гитхаб, и гитлаб подписывают свои запросы к вебхукам, используя его секретный ключ. Вот: https://developer.github.com/webhooks/#delivery-headers И вот: https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#secret-token > Просто возвращать return c каким-то ответом сервера, если не распарсим json? Порядочный веб-сервер должен отвечать в соответствие с протоколом http. Если клиент прислал невалидный json - следует ответить, например, кодом 400 Bad Request. Класть горутину паникой не нужно, можно просто залогировать ошибку.
Mike
не, 400 — это ваще не понял, невалидный — это 422
Oleg
не, 400 — это ваще не понял, невалидный — это 422
Нужно копаться в документации. 400 должен быть обобщением для любых ситуаций, когда ошибка в запросе клиента, насколько я помню.
Oleg
Я таки нагуглил :)) Все-таки при ошибках синтаксиса следует использовать 400: https://tools.ietf.org/html/rfc4918#section-11.2
Mike
ну такое, да. получается что если пришло говно, то 400, а если говно, но в джейсоне — 422
Daniil
sup
Daniil
вопрос. Это я невнимателен или в net/http/Server нету никакой обработки умерших соединений?
Daniil
типо клиент сделал запрос -> мы начали делать супер-дупер-ресурсоемкую работу -> клиент отключился -> мы отвечаем в уже закрытое соединение
Daniil
хотелось бы поймать этот эвент и отменить всю супер-дупер-ресурсоемкую работу
Илья
гугли context
Илья
и протаскивай контекст в глубину в логике
Daniil
спасибо
Alexey
> как лучше запускать и билдить проекты Команда go build (без аргументов) в папке пакета main собирает пакет целиком и кладет бинарник рядом. Не нужно перечислять файлы, это коряво, да :) > прийти на этот индпоинт может все что угодно И гитхаб, и гитлаб подписывают свои запросы к вебхукам, используя его секретный ключ. Вот: https://developer.github.com/webhooks/#delivery-headers И вот: https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#secret-token > Просто возвращать return c каким-то ответом сервера, если не распарсим json? Порядочный веб-сервер должен отвечать в соответствие с протоколом http. Если клиент прислал невалидный json - следует ответить, например, кодом 400 Bad Request. Класть горутину паникой не нужно, можно просто залогировать ошибку.
go build да, понял. но go run commits.go types.go github.go gitlab.go - это нормально? 😊 Про ответ сервера все понятно, в общем мысли у самого примерно такие же были, хотел просто убедиться, что все верно. Про планы реализации секретного токена есть в readme в разделе todo.
Brown
go run *
Brown
как то так помойму
Alexey
go run *
go run: no go files listed
Ivahaev
А это зачем вообще?
Brown
go run *.go
Ivahaev
Достаточно один файл, где функция main определена
Ivahaev
Разве нет?
Alexey
go run *.go
да, так работает
Alexey
Разве нет?
нет, так не работает
Alexey
основной код в файле commits.go Вот прежде всего что меня интересует: — глобальные переменные, правильно ли я поступил вынеся var bot *tgbotapi.BotAPI неред c main(), сделав bot доступным во всех функциях — файловая структура проекта, правильно ли я разбил код по файлам — как лучше запускать и билдить проекты: go run commits.go types.go github.go gitlab.go выглят как-то каряво... и такая же команда по build... — commits.go слушает входящие реквесты от gitlab http.HandleFunc("/gitlab", gitlabHandler), но прийти на этот индпоинт может все что угодно. Какой нибудь спам и пр.. Как обрабатывать такие ошибки? Просто возвращать return c каким-то ответом сервера, если не распарсим json? или как-то по другому обычно поступают? decoder := json.NewDecoder(req.Body) var api gitlab err := decoder.Decode(&api) if err != nil { panic(err) }
и остался вопрос 1 попрос к моему сообщению выше: — глобальные переменные, правильно ли я поступил вынеся var bot *tgbotapi.BotAPI неред c main(), сделав bot доступным во всех функциях
Brown
Я сам плохо отношусь к глобальным переменным, считаю это зло, считаю лучше передавать в функцию, но у вас это вроде набор функций верно?
Brown
https://www.bsuir.by/m/12_100229_1_98218.pdf
Brown
вот тут страница 347
Alexey
ну я поэтому и спрашиваю. Есть общее мнение, что глобально что-то задачать плохо... но вот в этому случае, если bot нужно вызывать не из main, то мне пришлось бы его передавать сначала в func github() потом из нее с func publish
Brown
в пдф страница 347 в книге 326
Alexey
какие еще есть способы решения таких вопросов кроме: - глобальных переменных - передачи в функцию
Brown
Это 2 подхода, глобальная плоха тем что не ясен цикл ее жизни, не понятно когда она создана, какое у нее состояние и тд
Brown
То что я скинул подробно расписанно когда использовать
Brown
там 2-3 страницы
Alexey
но третьего подхода нету? какой-то альтернативы, так?
Alexey
там 2-3 страницы
читаю, спасибо
Brown
Ну если это просто какой то сервис менеджер, в котором нет никаких состояний, то думаю можно, хотя я бы не стал
Alexey
Ну если это просто какой то сервис менеджер, в котором нет никаких состояний, то думаю можно, хотя я бы не стал
в моем случае bot - это объект обертки над телеграм api я объявляю переменную глобально. В main ее определяю. // Telegram var err error bot, err = tgbotapi.NewBotAPI(token) if err != nil { log.Fatal(err) } и потом в других местах ее использую bot.Send(msg)
Brown
Кстати оч класная книга, считаю обезательной к прочтиению
Brown
У меня в бумаге 2016 г
Brown
В электронке только 2012 находил
Brown
разницы там особой нет
engelbart
У меня есть глупый вопрос. У меня есть задача где всё время приходится мапы "объединять". Ну т.е map[string]int , суммировать значение по совпадающим ключам, добавлять отстуствующие. Сейчас сделано как for k,v:=range m2{ m1[k]+=v } вря ли тут что то ещё можно придумать, но это так часто происходит, что уже ужастно тормозит. Нет ли случайно каких то советов, как это улучшить? Может хранить иначе, другие структуры. Задача примерно как считать частотность слов в тексте. И такие мапы приходят как будто с разных параграфов и текстов.
Anonymous
может string на числовое значение попробовать заменить
Anonymous
что-то вроде кодов хаффмана
engelbart
помойму не выйдет же. если отельно справочник вести то мне в том справочнике пополнять
Anonymous
Вроде бы у гугла была какая-то супер быстрая хэш таблица, может через cgo сделать
engelbart
не помните имён?
Anonymous
http://incise.org/hash-table-benchmarks.html
engelbart
Спасибо, понятия не имею как это юзать, но гляну
Anonymous
На C++ переключиться, а результат в go отдавать :)
engelbart
эх
engelbart
может какие нить волшебные базы бывают
engelbart
что б туда мэпы передавать а оно там как нить паралельно
engelbart
мне даже синхроннывй ответ то не нужен
Anonymous
Кстати, может попробовать распаралелить
engelbart
Вынести хранение куда нить, и поставить фоновый процесс пусть себе объединяет
Anonymous
Не думаю, что у go для этого можно много оптимизаций придумать, если только распараллелить
engelbart
1. Значения не сортированы 2. Обычно один меп сильно больше другого по размеру (аккумулирует данные) поэтому я делаю range по меньшему 3. Ключи по размеру все одинаковы, и рандомны. Хорошая аналогия слова в тексте. 4. Элементов десятки тысяч
Daniil
Если нет - плохо. Можешь посмотреть как в яве у строки подсчитывается хэш
Daniil
Сразу же вопрос, а в го можно задать в мапу кастомный компаратор или объявить таковой для типа данных?
Brown
не то но примерно
Daniil
Но можно хранить строку и хэш к ней рядом. Есть маленькая надежда что го сначала сравнит хэш а потом строку
Daniil
Тогда взлетит)))