Igor Panasyuk | IGORoutine Programming
2.11K subscribers
112 photos
8 videos
75 links
Тимлид Яндекса, разрабатываю эквайринг, обеспечивающий обработку всех платежей компании. Доцент практики в ИТМО, веду несколько курсов, также преподаю в ШАД. Выступаю на конференциях, делюсь опытом в соцсетях и помогаю развитию Go-сообщества
Download Telegram
Только успел отправить призы с новогоднего розыгрыша - уже наступил новый праздник)

Поздравляю мужскую часть канала с 23 февраля!

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

В этот день желаю вам здоровья, силы и чести.
Становиться лучше с каждым днём - чтобы иметь возможность защитить себя, свою семью и свои ценности.

Буду продолжать радовать вас новыми видео и проектами. Совсем недавно выпустил разбор Go 1.26. Честно говоря, про сам язык Go я уже будто разобрал всё, что можно. Очень много видео-лекций сейчас лежат и ждут монтажа.

Поставьте, пожалуйста, 🙂 , если вам было бы интересно увидеть их в сыром формате.

На текущий момент хочу начать разбирать всё, что связано с архитектурой проекта на Go и не только. До конца февраля выйдет полноценный разбор gRPC, начиная от внутреннего устройства HTTP/2, заканчивая проектированием API и генерацией кода.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
10124🫡14❤‍🔥114🖕3
🙂 Этот день настал

Последние пару месяцев меня очень часто спрашивали про то, когда будет запуск курса по Go.

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

Что скрывать, язык Go действительно набрал огромную популярность. В этом году это топ-1 курс по выбору в ИТМО.

То есть, мало того, что AI и кризис создают инфляцию знаний, так ещё и подрастает конкурирующее поколение, которое сейчас учится в ведущих вузах страны, в том числе на моих курсах.

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

Единственный способ победить это повысить свою компетентность.

Как раз для этого запускаю уникальный и ограниченный поток «The Nature of Go», в котором собрал симбиоз своих нескольких курсов.

База computer science, внутреннее устройство Go, разработка микросервисов, применение AI, написание резюме, софтскиллы и прохождение собеседований.

Полный набор для того, чтобы адаптироваться к новой реальности и не проиграть.

👉👉 Link
👉👉 Link
👉👉 Link
Please open Telegram to view this post
VIEW IN TELEGRAM
727🤩1410🔥52
🙂 gRPC на Go: от внутреннего устройства до архитектуры

Как и говорил, хочу начать разбирать всё, что связано с архитектурой проекта на Go и не только.

В новом видео подробно разобрал тему gRPC, начиная от истории создания и внутреннего устройства HTTP/2, заканчивая генерацией кода на Go через buf (easyp). Приятного просмотра!

▶️ YouTube
📱 VK Видео
🤪 Дзен
🟣 Rutube

🙂 ПАНЕЛЬ УПРАВЛЕНИЯ 🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
8❤‍🔥33🤩6433
Forwarded from Yandex for Backend
🔍 Что нового в последней версии Go

Многие продукты Яндекса используют этот язык в своих сервисах: от инфраструктуры автономного транспорта до продуктовых сервисов финтеха. Поэтому разработчики постоянно расширяют экспертизу в Go: изучают лучшие практики, делятся опытом, проводят митапы и подробно разбирают нововведения.

Сейчас есть отличный повод этим заняться: 10 февраля вышел Go 1.26.

👩‍⚕️ Мы попросили Игоря Панасюка из группы продуктовой разработки платежей разобрать ключевые изменения релиза. Давайте посмотрим, что интересного принесла новая версия и на что стоит обратить внимание.

🔶 Для тех, кто хочет погрузиться глубже, в личном канале Игоря есть пост и видео с материалами по теме.

📺 И ещё несколько полезных видео:

🟢 Сборщик мусора в Go 1.26
🟢 Ассемблер и SIMD в новых map и GC

🐚 А что вам показалось наиболее интересным в обновлении? Пишите в комментариях.

Подписывайтесь:
💬 @Yandex4Backend
📹 @YandexforBackend
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
724124🔥2
Forwarded from igoroutine.courses
😢😢 От этого data race не спасает даже race detector

Data race это частный случай race condition. Определять термин data race на самом деле можно по-разному.

Самое простое определение:
Состояние во время исполнения, когда две операции над переменной происходят из разных горутин без синхронизации, при этом хотя бы одна из них является записью.

Чуть более сложное:
Состояние во время исполнения, когда две конфликтующие операции над переменной происходят из разных горутин без синхронизации.

И самое сложное на основании формализма из Go memory model:
Состояние во время исполнения, когда две конфликтующие операции над переменной нельзя разделить отношением happens before


Казалось бы, да ну их, есть прекрасный инструмент race detector, который инструментриует программу при компиляции и позволяет во время исполнения находить data race.

Но, внезапно, выясняется, что он не всегда может найти проблему. Это напрямую следует из его устройства.

Пример:

Мейнтейнеры Go пытались реализовать такой интерфейс:


type Cron interface {
Run(ctx context.Context, action func(), next func() time.Duration)
}


Реализация должна вызывать action, ожидая перед каждым запуском next() времени. После отмены контекста не должно быть вызовов action.

Такой подход на практике очень часто используется, например:

• HTTP ретраи
• Service discovery
• Adaptive polling
• Keepalive / heartbeat
• Любые задачи с backoff

Сходу у них получилась следующая реализация:


func (c *cronImpl) Run(ctx context.Context, action func(), next func() time.Duration) {
var t *time.Timer

t = time.AfterFunc(next(), func() {
select {
case <-ctx.Done():
return
default:
action()
t.Reset(next())
}
})

<-ctx.Done()
}


Запускаем тесты:



func TestCron(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
c := New()

var n atomic.Int64
next := func() time.Duration {
if n.Add(1) <= 5 {
return 0
}

return 1 * time.Second
}

var calls atomic.Int64
ctx, cancel := context.WithCancel(t.Context())

t.Cleanup(func() {
cancel()
})

done := make(chan struct{})
go func() {
defer close(done)

c.Run(ctx, func() {
calls.Add(1)
}, next)
}()

synctest.Wait()

require.Greater(t, calls.Load(), int64(0))

cancel()
synctest.Wait()

select {
case <-done:
default:
t.Fatalf("Run did not exit after cancel")
}
})
}


Которые успешно проходят даже с race detector'ом.

Но в этой реализации действительно есть data race, и race detector его не находит.

👉👉 Пишите ваши предположения в комментариях, пост с правильным ответом выйдет в ближайшее время.

Ссылка с примером использования: https://go.dev/play/p/Fq-yNa0wXWj

P.S. Пожалуйста, те, кто проходил курс и решал это задание на практике, не пишите сразу правильный ответ)
Please open Telegram to view this post
VIEW IN TELEGRAM
9🤔8👍211
Forwarded from igoroutine.courses
😎😎 От этого data race не спасает даже race detector

Продолжение к предыдущему посту.

Итак, разработчик из Go team написал такую реализацию:


func (c *cronImpl) Run(ctx context.Context, action func(), next func() time.Duration) {
var t *time.Timer

t = time.AfterFunc(next(), func() {
select {
case <-ctx.Done():
return
default:
action()
t.Reset(next())
}
})

<-ctx.Done()
}

func main() {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*10)
defer cancel()

c := cronImpl{}
c.Run(ctx,
func() {
fmt.Println("Hello, @igoroutine")
},
func() time.Duration {
return time.Second
},
)
}


Всё ожидаемо работает:

Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine
Hello, @igoroutine

Program exited 0.


Мы, как ответственные люди, дополнительно написали тест. Более того, включили race detector при компиляции.

go test -v -race ./...



func TestCron(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
c := New()

var n atomic.Int64
next := func() time.Duration {
if n.Add(1) <= 5 {
return 0
}

return 1 * time.Second
}

var calls atomic.Int64
ctx, cancel := context.WithCancel(t.Context())

done := make(chan struct{})
go func() {
defer close(done)

c.Run(ctx, func() {
calls.Add(1)
}, next)
}()

synctest.Wait()

require.Greater(t, calls.Load(), int64(0))

cancel()
synctest.Wait()

select {
case <-done:
default:
t.Fatalf("Run did not exit after cancel")
}
})
}


=== RUN TestCron
--- PASS: TestCron (0.00s)
PASS


😎😎 Всё успешно, выкатываем приложение на production и радуемся жизни.

🫡🫡Но, внезапно, раз в неделю появляется ошибка:
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x1009927fc]


Пробуем дебагать и снова запускать тесты. Для надёжности прогоняем их с count=10000:
go test -v -count=10000 ./...
PASS
ok 0.787s


Попробуем запустить с race detector'ом и count=100:
go test -v -race -count=100 ./...
PASS
ok 4.079s


😳😳 Безумие!

От безысходности запускаем тесты с race detector'ом и count=1000000 и видим вот это:


WARNING: DATA RACE
Read at 0x00c0000024a0 by goroutine 3543:
cron.go:30 +0x90 // t.Reset(next())

Previous write at 0x00c0000024a0 by goroutine 3541:
cron.go:24 +0x194 // t = time.AfterFunc(next() ...

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x1050ae7fc]


Всё дело в том, что AfterFunc внутри создаёт отдельную горутину:


func AfterFunc(d Duration, f func()) *Timer {
return newTimer(when(d), 0, goFunc, f, nil)
}

func goFunc(arg any, seq uintptr, delta int64) {
go arg.(func())()
}


При очень маленьком d в этом коде


t = time.AfterFunc(next(), func() {
...
t.Reset(next())
})


Горутина с t.Reset может начать исполняться раньше, чем значение будет сохранено в t. Соответственно, получается nil pointer dereference. На самом деле причина может быть в аппаратной реализации, например, t может находиться в кэше ядра. И таких «аппаратных» объяснений может быть очень много в зависимости от архитектуры.

С точки зрения Go memory model это не важно.

Важно, что мы пишем (t = ...) и читаем (t.Reset) общую переменную без синхронизации. Это data race по определению.

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

Более того, эту реализацию можно переписать более эффективно, чтобы избежать создания лишней горутины.

Это как раз одно из многочисленных заданий на курсе The Nature of Go.

👉👉 Пишите в комментариях, какие интересные баги вы находили с помощью race detector'a!
Please open Telegram to view this post
VIEW IN TELEGRAM
4🤯13👍3😱21
❤️Традиционно поздравляю всех дам с 8 марта!

Случайно решил почитать про историю праздника на wiki.

Сознание определенно расширилось
Please open Telegram to view this post
VIEW IN TELEGRAM
21113
This media is not supported in your browser
VIEW IN TELEGRAM
2193
👉👉 100+ реакций под постом с материалами

Недавно выкладывал пост, после которого по реакциям понял, что многим интересно увидеть мои видео-лекции по разным направлениям.

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

Как раз недавно провёл в ШАД (Школа анализа данных от Яндекса) лекции на курсе Go про продвинутое тестирование и concurrency. По concurrency получилось хорошо пройтись по базе, не углубляясь в нюансы.

Из интересного, сам перед лекцией разбирался с новой реализацией sync.Map (HashTrieMap), которую добавили в Go 1.24, там все оказалось довольно интересно))

Про тестирование за 3 часа получилось рассказать почти все, что можно, начиная от устройства пакета testing, заканчивая интеграционными тестами и настройкой CI. Как раз эта большая лекция про тестирование будет одной из первых на сайте.

😎😎 Ну а для тех, кто хочет комплексно и всеобъемлюще погрузиться во все тонкости и нюансы, напоминаю, что в конце апреля стартует уникальный поток The Nature of Go, пока ещё есть места.

👉👉 Link
👉👉 Link

🙂 ПАНЕЛЬ УПРАВЛЕНИЯ 🙂
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
84017🥰8🙏11