Lasiar работает 💡
161 subscribers
7 photos
47 links
Про Golang и около того

help: @Vallder
Download Telegram
Кажется что в Go скоро появятся новые директивы:
//go:fix inline 

//go:fix forward


Они будут нужны для новой миграционной тулзы: go fix, которая переписывает на новый API после обновления Go (подробнее можно почитать тут).

На сколько я понял:
//go:fix forward — просто меняет обратно совместимую сущность.

А c //go:fix inline чуть муторнее, go fix будет просто инлайнить тело функции

К примеру:
package a

func f() {
One() // want `inline call of a.One`

new(T).Two() // want `inline call of \(a.T\).Two`
}

type T struct{}

//go:fix inline
func One() int { return one } // want One:`goFixInline a.One`

const one = 1

//go:fix inline
func (T) Two() int { return 2 } // want Two:`goFixInline \(a.T\).Two`


Меняется на:
package a

func f() {
_ = one // want `inline call of a.One`

_ = 2 // want `inline call of \(a.T\).Two`
}

type T struct{}

//go:fix inline
func One() int { return one } // want One:`goFixInline a.One`

const one = 1

//go:fix inline
func (T) Two() int { return 2 } // want Two:`goFixInline \(a.T\).Two`


Как по мне, выглядит несколько странно.

P.S.
Не совсем понятно как будет решаться проблема с пересечением скоупа.
Кажется тогда код с которым осуществляется работа может стать максимально некрасивым :с
👍411👨‍💻1👀1💅1👾1
Является ли число Pi корректным destination для ping?

PI=3.14159265 ping ${PI}
Anonymous Quiz
62%
Да
38%
Нет
🤨3🍌1💅1👾1
Постом выше спрашивал про ping.
А вот и ответ:

🥁🥁🥁

Число Pi для команды ping является корректным аргументом.

Почему?
Ping использует функцию inet_aton().

И man, говорит про эту функцию следующее:
a.b.c.d
Each of the four numeric parts specifies a byte of the address; the bytes are assigned in left-to-right order to produce the binary address.

a.b.c

Parts a and b specify the first two bytes of the binary address. Part c is interpreted as a 16-bit value that defines the rightmost two bytes of the binary address. This notation is suitable for specifying (outmoded) Class B network addresses.

a.b

Part a specifies the first byte of the binary address. Part b is interpreted as a 24-bit value that defines the rightmost three bytes of the binary address. This notation is suitable for specifying (outmoded) Class C network addresses.

a

The value a is interpreted as a 32-bit value that is stored directly into the binary address without any byte rearrangement.

В итоге, пингануть 127.0.0.1 можно просто через ping 127.1 или через 0x7F.1, или через 2130706433...
🤯🤯🤯

Откуда это все пошло:

- 1983, 4.2BSD. Первое появление подобной логики, в функции inet_addr().

- 1990, 4.3BSD-Reno. Появление функции inet_aton().

- 1999, Networking Services (XNS) Issue 5.2. Описывает inet_addr(), с подобным синтаксисом.

- 2004, POSIX. Взятое из XNS ассоциация IEEE добавляет в POSIX функции: inet_addr(), inet_ntoa(), сохраняя поведение (link, и через поиск этих функций).

- 2005, RFC 3986, Запрещает подобный синтаксис для URI, хотя в chromium based браузерах оно работает http://2915189091 (ссылка не работает на этом тексте, так что только через ^c ^v).

- 2020, Golang. Создано issue с предложением добавить описанную выше логику в пакет net, спустя почти пять лет (4 декабря 2024) закрывают issue как "not planned".
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍2🔥2👾2❤‍🔥1😁1😱1💅1
Скорее всего уже на этой неделе будет релиз Go 1.24.
🎉🎉🎉

Об это в прошлый вторник объявила Cherry Mui, которая отвечает за выпуск релизов (и не только).
1.24.0 is planned to be released next week



И создан milestone для 1.25.
🔥4💅31🆒1👾1
Ура, Go 1.24 релизнулся!
🎉🎉🎉

Буквально пару часов делал пост про это https://t.me/LasiarAtWork/42
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥10👏311👌1💅1
Ранее писал про новую директиву //go:fix inline.

Alan Donovan из Go team недавно сделал PR, в котором добавил в пакеты ioutil и reflect эту директиву для некоторых функций.

Здесь выглядит симпатично, *НО* это сделал инженер из Go team, а какое качество будет у разработчиков сторонних библиотек?

В целом, я буду делать по старинке, через golangci-lint искать deprecated функции и руками буду править.

Как мне кажется, лучше было бы через go vet предупреждение сделать, а не править так исходный код.
5🔥1💅1💘1👾1
Недавно вспоминал о своем докладе: "Почему Docker написан на Go", который я готовил год назад для подлодки.

В этом докладе вас ждет:
- 🕵️ Теория заговора
- 📅 История контейнеризации с 1979 года
- 💔 Почему K8s отказался от Docker (спойлер: не совсем отказался)
- 📑 Не совсем публичные слайды команды dotCloud (ex Docker, inc)

📺 Смотреть

P.S. Все еще актуально, как и год назад! 👀
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥95🥰2
Ранее говорил о GOMAXPROCS и cgroup.

И вот в новой версии Go (1.25) уже не понадобится библиотека github.com/uber-go/automaxprocs, так как cgroup для GOMAXPROCS будет учитываться "из коробки".
Уже даже документация обновлена для master ветки.
🔥1032🍓1💅1
Кстати, про 1.25:
сегодня-завтра должен выйти Go 1.25 RC1
🔥72🍾2💅1
Я пропустил что в Go 1.22 добавили работу с относительно новой сущностью Linux pidfd.

Зачем это в Linux?
Работа с PID по сути всегда гонка:
- Получаем PID процесса (например, PID=100);
- Процесс умирает,
- ОС создает новый процесс, переиспользуя PID=100;
- В итоге мы работаем с совершенно другим процессом.

Это причина уязвимостей: CVE-2019-6133, CVE-2019-15790... А так же причина одного из issue у Go .

Решение
В Linux 5.1 появился системный вызов pidfd_open(pid_t pid, unsigned int flags). Он даёт ссылку на конкретный процесс, а не на PID, который может быть переиспользован.
Дальше (вплоть до ядра 6.5) добавили и другие методы получения pidfd.

Что в Go?
И уже в Go 1.23 в методах и функциях, которые относятся к процессу используется по возможности pidfd.
🔥9👍4🍾2👨‍💻2😁1💅1
В последнее время довольно часто приходится работать напрямую с TCP/UDP, а иногда и по SSH.

В таких случаях особенно важно использовать connection pool и следить, чтобы соединение не "умерло" - - так мы избегаем накладных расходов на рукопожатие (особенно важно если в протоколе есть дополнительные "телодвижения").

Отлично в этом помогает библиотека от jackc -- puddle (автор, кстати, того же pgx).

Грубо говоря, это sync.Pool{}, только не для памяти, а для ресурсов, причём с возможностью ограничить количество создаваемых экземпляров. Если лимит достигнут, попытка получить новый ресурс блокируется до появления свободного -- что помогает контролировать нагрузку и избегать перерасхода соединений.

Примеры использования вне README можно посмотреть в исходниках pgx (файл pgxpool/pool.go) и ch-go (файл chpool/conn.go).

Ну и небольшой пример из README:

func main() {
constructor := func(context.Context) (net.Conn, error) {
return net.Dial("tcp", "127.0.0.1:8080")
}
destructor := func(value net.Conn) {
value.Close()
}
maxPoolSize := int32(10)

pool, err := puddle.NewPool(&puddle.Config[net.Conn]{Constructor: constructor, Destructor: destructor, MaxSize: maxPoolSize})
if err != nil {
log.Fatal(err)
}

// Acquire resource from the pool.
res, err := pool.Acquire(context.Background())
if err != nil {
log.Fatal(err)
}

// Use resource.
_, err = res.Value().Write([]byte{1})
if err != nil {
log.Fatal(err)
}

// Release when done.
res.Release()
}
👍9🔥7
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Уххх!
В Go начали завозить intrinsics для SIMD.

То есть, возможно, можно будет вызывать SIMD инструкции напрямую, прямо из Go кода.

Для теста можно подтянуть ветку через gotip:
go install golang.org/dl/gotip@latest  # если ещё не установлено
gotip download dev.simd # собираем ветку dev.simd


Правда, пока что поддержка только для amd64, так что локально потыкать у меня не получится :(

Как только появится arm -- обязательно сделаю бенчмарки и поделюсь результатами.

Кратко о текущем состоянии -- в комментарии Cherry Mui: https://github.com/golang/go/issues/73787#issuecomment-3208178910
🔥31👏1🍓1💅1👾1
Всем привет!)

Второй год участвую в программном комитете конференции E-CODE, помогаю с формированием трека backend.

Буду лично на мероприятии, оно пройдёт 13-14 сентября.

Если вы тоже там будете -- можно пообщаться в перерывах между докладами)
6🥰4🐳1🍓1👾1
В Go завезли поддержку valgrind -- утилиты, которая может обнаруживать утечки памяти.

Это, конечно, круто, но зачем?

На этот вопрос ответил автор CL, а также security team lead в Golang -- Roland Bracewell Shoemaker.

Основная цель -- находить функции, которые выполняются не за константное время.

Тут у кого-то может возникнуть вопрос:
Зачем нам функции, которые работают за константное время? Разве мы не хотим, чтобы они выполнялись как можно быстрее?
А тут стоит посмотреть на роль того, кто добавил CL SECURITY team lead.

В криптографии очень важно, чтобы функции выполнялись за константное время.
Если передавать разные входные данные и замерять время выполнения, можно провести timing oracle attack.

Тривиальный и упрощённый пример:
Мы побайтово сравниваем два хеша и при первом несовпадении выходим из функции раньше.

Тогда атакующий может подбирать хеш, ориентируясь на время выполнения запроса:
если оно немного замедлилось -- значит, один символ уже верный.

Чтобы предотвратить это, нужно, чтобы доступ к памяти и ветвление кода были одинаковыми для всех входных данных.

Для проверки этого как раз и нужен valgrind -- он отслеживает, какие области памяти и регистры используются в каждой ветке исполнения.

Подробнее про использование valgrind в рамках поиска функции, которые выполняются не за константное время можно почитать тут репозиторию аж 15 лет.
🔥93👾2💅1
TL;DR
Изменения пользователя и прав в Dockerfile при копировании можно выполнить одной командой.

COPY [--chown=<user>:<group>] [--chmod=<perms> ...] <src> ... <dest>


Docker использует файловые системы, c поддержкой Union mount -- накладывание одного дерева файлов на другой.

Одно такое дерево файлов в терминологии Docker называется слой (layer).
Слои нельзя изменить, изменения записываются в новый слой.

Каждая инструкция в Dockerfile создает отдельный слой.

И когда мы копируем файлы и потом через RUN меняем права или принадлежность файла, файлы полностью копируются ещё раз в новый слой, уже с обновлёнными атрибутами.

Особенно больно, когда у нас много файлов или они тяжелые.
Для изменения атрибутов, приходится все копировать в новый слой.

Чтобы избежать этого можно сразу указать --chown и/или
--chmod при копировании.


┌─────────────────────────┐
│ Верхний слой │ ← Изменения прав (chmod/chown)
├─────────────────────────┤
│ Данные приложения │ ← COPY . /app
├─────────────────────────┤
│ Базовый образ (OS) │ ← FROM ubuntu/alpine/etc
└─────────────────────────┘
6👍3🥰2👾21💅1
Потихоньку в стандартную библиотеку Go добавляют работу с generic.

В Go 1.26 добавили функцию errors.AsType[E error](err error) (E, bool).

Релиз Go 1.18, где появились generic был 25 марта 2022 года, а уже через 10 дней появился issue, где предлагалось добавить generic функцию в пакет errors.
Только первоначально говорилось об изменении errors.As(), возможно из-за этого только спустя три года добавилась функция errors.AsType().

В целом -- мне нравится.

Во-первых, это выглядит симпатично:

pathError, ok := errors.AsType[*fs.PathError](err)


Во-вторых, это значительно быстрее:
Код бенчмарка: https://go.dev/play/p/AcQyInSlR7D
Результат:

goos: darwin
goarch: arm64
pkg: test
cpu: Apple M4 Pro
│ as.txt │ as_type.txt │
│ sec/op │ sec/op vs base │
Errors-12 33.480n ± 1% 2.113n ± 1% -93.69% (p=0.000 n=20)

│ as.txt │ as_type.txt │
│ B/op │ B/op vs base │
Errors-12 8.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=20)

│ as.txt │ as_type.txt │
│ allocs/op │ allocs/op vs base │
Errors-12 1.000 ± 0% 0.000 ± 0% -100.00% (p=0.000 n=20)
🔥43💘2👍1💅1
https://t.me/LasiarAtWork/53

В Go 1.26 добавят реализацию SIMD для amd64.

При этом возможно этот пакет будет использоваться в green tea (новый GC, который будет включен по умолчанию в Go 1.26), что должно ускорить добавление других архитектур в пакете simd.
🔥5
Там Nvidia в ядре Linux готовят сетевую подсистему под 1600Gbps (8x200Gbps).

Скорость просто невероятная!

Думаю что это необоходимо для нейроных сетей.

Немного контекста:
Nvidia с 2020 года владеет компанией Mellanox, которая выпускает сетевое оборудование для HPC.
🔥42