Forwarded from How to Go wrong (Alexey Palazhchenko)
Лучшая четверть организаторов GopherCon Russia (не я) делает камерный четырехдневный Go-кэмп в Черногории. С 13-ого по 16-ое октября будет летний лагерь, Kubernetes операторы, горы, PyTorch в Go, отдых, создание игр на Go. Подробности тут, а наш Go-чат делает разыгрыш скидки в 15%.
🔥5
😱 Простите не про Go. 22 года работаю с MySQL. CRUD для веба. Один раз что-то сложное делал, но специфическое. Не прямо чтобы DBA, я к этому. И тут фигня случается — 2млн. строк, есть индекс по int-полю, выборки строк под 20. Тормозит и всё тут
😱 Я уже и так, и сяк, и innodb в память вытащил. Ладно, думаю, дошло дело до изучения Explain. И тут вдруг вижу - индекс по колонке, по которой выбираю, есть, но explain показывает ALL.
WTF?!!!!
🤙 Просто
WTF?!!!! 2024 год на дворе
😱 Я уже и так, и сяк, и innodb в память вытащил. Ладно, думаю, дошло дело до изучения Explain. И тут вдруг вижу - индекс по колонке, по которой выбираю, есть, но explain показывает ALL.
WTF?!!!!
🤙 Просто
ANALIZE TABLE ...
спасает ситуциюWTF?!!!! 2024 год на дворе
#swagger #oauth 🖌 Произвёл рефакторинг своего летнего поста про oauth2 в go-swagger
☝️ Я работаю с swagger только в режиме генерации кода. Генерация спецификации по коду делает код более гибким. Однако и возможностей ошибиться намного больше, чем при генерации кода по спецификации
☕️ Переделывал одну вещь по работе и не смог найти в go-swagger для
ℹ️ Что такое client credentials grant? Это когда клиенту API надо сходить с
👉 Для варианта
☝️ Главное не забыть у
и добавить в
👍 Flow полностью соответствует RFC 6749. Встроенный в go-swagger Swagger-UI умеет этот flow авторизовать. Он запрашивает
‼️ Обратите внимание, что go-swagger не учитывает формата выдаваемого токена — он может быть любым. Поле
☝️ Я работаю с swagger только в режиме генерации кода. Генерация спецификации по коду делает код более гибким. Однако и возможностей ошибиться намного больше, чем при генерации кода по спецификации
☕️ Переделывал одну вещь по работе и не смог найти в go-swagger для
security.type="oauth2"
значение для flow для client credentials grant
. Через несколько часов поисков и экспериментов, я всё-таки обнаружил нужный flow. Но считаю, что в документации это не очевидноℹ️ Что такое client credentials grant? Это когда клиенту API надо сходить с
client_id
и client_secret
(считайте логин и пароль) на сервер авторизации и запросить токен доступа. А к ресурсам ходить уже с этим токеном. Токен указывается в заголовке. Обычно токен представляет собой JWT (данные в json. подписанные и закодированные в base64 с определёнными полями, указывающими что это за токен, срок действия, область действия - scope
и т.д.). Принципиальное отличие от авторизации пользователя — права принадлежат приложению. Хотя, на практике в большинстве случаев права приложений строго равны правам, создавших их пользователей👉 Для варианта
client credentials grant
в go-swagger есть специальный flow: application (совершенно неочевидное название). Из обязательных полей только tokenURL
, который может быть в свою очередь в этом же API:securityDefinitions:
OauthSecurity:
type: oauth2
flow: applicatiom
tokenUrl: '/token'
scopes:
admin: Admin scope
user: User scope
☝️ Главное не забыть у
/token
, если он локальный, указать авторизацию Basic
: paths:
/token:
post:
security:
- Basic: []
и добавить в
securityDefinitions
:securityDefinitions:
Basic:
type: basic
👍 Flow полностью соответствует RFC 6749. Встроенный в go-swagger Swagger-UI умеет этот flow авторизовать. Он запрашивает
client_id
и client_secret
, и scope
у пользователя. Пару client_id
и client_secret
он сам превращает в заголовок Authorization: Basic xxxx...
(как и положено по RFC). Он сам получает access_token
по ссылке tokenURL
, которую он распознаёт, и потом с этим токеном работает в API через заголовок Authorization: Bearer xxxx...
‼️ Обратите внимание, что go-swagger не учитывает формата выдаваемого токена — он может быть любым. Поле
scope
в блоке security
носит справочную информацию и передаётся в функцию обработки авторизации для справки. Опознания JWT, его разбора и сравнения scope
не происходит/user:
post:
security:
- JWT:
- "user:create"
Forwarded from How to Go wrong (Alexey Palazhchenko)
Tailscale портировали на Plan 9, попутно пофиксив и Go, и сам Plan 9: https://tailscale.com/blog/plan9-port
Tailscale
Porting Tailscale to Plan 9
Securely connect to anything on the internet with Tailscale. Built on WireGuard®️, Tailscale enables you to make finely configurable connections, secured end-to-end according to zero trust principles, between any resources on any infrastructure.
This media is not supported in your browser
VIEW IN TELEGRAM
🥃 Видимо я переделаю это не раньше второго пришествия. Вдруг кому понадобится. Или я когда-нибудь переведу на английский/литовский и актуализирую. pdf первым каментом
🥰7
🍭 А вот тут чуть магии. Любите оптимизировать и мерять скорости? Правда? Это точно надо переработать и перевести. Наслаждайтесь
Длинные селекторы в Go
Нередко встречаю такой паттерн:
Функционально всё корректно, но цепочка
Я предпочитаю предварительно закэшировать конечный объект, создав локальный псевдоним (alias binding):
Почему это выглядит чище:
* Уменьшение числа селекторов (Number of Selectors, NOC): глубина доступа падает с 3 до 1, чтение ускоряется линейно
* Семантическая прозрачность (semantic transparency): конечный объект (
* Нулевая стоимость абстракции (zero-cost abstraction): компилятор Go инлайнит псевдоним, нет лишних аллокаций и нагрузки на GC
* Снижение синтаксического шума (syntactic noise), анализаторы IDE реже ошибаются (поверил гуглу — сам не встречал)
P.S. ChatGPT конечно неплохо поработал с моим сумбурным текстом, добавил терминов, которые я и не слышал даже. Выглядит интересно
А вы боретесь с длинными селекторами (selector hell)?
Нередко встречаю такой паттерн:
x := k.c.y.SetX()
// ...
if k.c.y.Exists() {
// ...
Функционально всё корректно, но цепочка
k.c.y
дважды нагружает зрение и увеличивает когнитивную нагрузку (cognitive load) — мозг вынужден каждый раз «проходить» всю селекторную цепочку (dot/point-chasing).Я предпочитаю предварительно закэшировать конечный объект, создав локальный псевдоним (alias binding):
y := k.c.y
x := y.SetX()
// ...
if y.Exists() {
// ...
Почему это выглядит чище:
* Уменьшение числа селекторов (Number of Selectors, NOC): глубина доступа падает с 3 до 1, чтение ускоряется линейно
* Семантическая прозрачность (semantic transparency): конечный объект (
y
) получает собственный идентификатор, сразу видно его роль* Нулевая стоимость абстракции (zero-cost abstraction): компилятор Go инлайнит псевдоним, нет лишних аллокаций и нагрузки на GC
* Снижение синтаксического шума (syntactic noise), анализаторы IDE реже ошибаются (поверил гуглу — сам не встречал)
P.S. ChatGPT конечно неплохо поработал с моим сумбурным текстом, добавил терминов, которые я и не слышал даже. Выглядит интересно
А вы боретесь с длинными селекторами (selector hell)?
👍6
Путь Golang
Длинные селекторы в Go Нередко встречаю такой паттерн: x := k.c.y.SetX() // ... if k.c.y.Exists() { // ... Функционально всё корректно, но цепочка k.c.y дважды нагружает зрение и увеличивает когнитивную нагрузку (cognitive load) — мозг вынужден каждый…
И я тут же словил это в своём собственном VPN-боте. Ай я молодец
😁1
🔥🔥🔥 У меня пригорает от jira. Это уже 6-ой круг объяснения, что не так
А НАТЫКАЙТЕ МНЕ ТАМ СПРАВА ВВЕРХУ ГОЛОСОВ ЗА ТИКЕТ!!!!!! ПОЖАЛУЙСТА
https://jira.atlassian.com/browse/JSDCLOUD-16830
А НАТЫКАЙТЕ МНЕ ТАМ СПРАВА ВВЕРХУ ГОЛОСОВ ЗА ТИКЕТ!!!!!! ПОЖАЛУЙСТА
https://jira.atlassian.com/browse/JSDCLOUD-16830
👻 На собеседованиях мешается «много языков». Только что «облажался», зависнув на условном
m["key1"]++
. Потому что оно в разных языках по-разному и я забыл в каком что😁3🤯2
😮 Ой. А вы знали о такой ссылке?
https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize
☝️ Вкратце — это тулза (и описание) для замены устаревших конструкций более модными. Из этой новости я узнал про
https://pkg.go.dev/golang.org/x/tools/gopls/internal/analysis/modernize
☝️ Вкратце — это тулза (и описание) для замены устаревших конструкций более модными. Из этой новости я узнал про
min()
/ max()
pkg.go.dev
modernize package - golang.org/x/tools/gopls/internal/analysis/modernize - Go Packages
Package modernize providers the modernizer analyzer.
👍7
👻 Ухожу в монастырь. Пропустил
👍 Кстати, очень хороший пример уместности дженериков
slices.Contains()
. Я не просто так пишу сюда, если что. Может не один я такой не слежу👍 Кстати, очень хороший пример уместности дженериков
👍5👏2
For the foreseeable future, the Go team will stop pursuing syntactic language changes for error handling. We will also close all open and incoming proposals that concern themselves primarily with the syntax of error handling, without further investigation
https://go.dev/blog/error-syntax
😅 Уф, пронесло
P.S. Взял отсюда: https://t.iss.one/HowToGoWrong/233
go.dev
[ On | No ] syntactic support for error handling - The Go Programming Language
Go team plans around error handling support
🥰3👍2👎1🤔1
Forwarded from 🏳️Filipp Kulin
Я помню как-то решил в 2014 году таки ознакомиться с Ansible. Ну такое открываю, пытаюсь через шелл с судо ад хок сделать и сосу тунца.
Мучаюсь дня два. Лезу в код.
1. Паттерн "отлова" приглашения ввести пароль сделан только на linux. Делаю багрепорт с предложением поправить
Мучаюсь ещё два дня. Лезу в код.
2. Вызывается
Делаю багрепорт с предложением поправить.
Запускаю две каманды ад хок и радостно забываю про такой способ навсегда, перейдя на ключи
Мучаюсь дня два. Лезу в код.
1. Паттерн "отлова" приглашения ввести пароль сделан только на linux. Делаю багрепорт с предложением поправить
Мучаюсь ещё два дня. Лезу в код.
2. Вызывается
sh
с гнушной либой разбора параметров и неверный параметр -c
, если другие либы. Во freebsd не работает. Делаю багрепорт с предложением поправить.
Запускаю две каманды ад хок и радостно забываю про такой способ навсегда, перейдя на ключи
В jira есть два формата именования кастомных полей (или даже три). И есть язык JQL для поиска. Так вот для разных операторов условий нужно применять свой формат имени поля ("=" и "IS EMPTY" работают каждый только со своим форматом). А для установки значения поля - тоже только один из них. И главное — не перепутать
🔥1