Чего ещё не хватает для Graceful Shutdown? Все функции sql-lite имеют двойников с контекстом, например: .Exec вызывает .ExecContext с базовым context.Background(). У меня не хватило ума реализовать nested-контекст для стораджа и для веб-сервера. Как оно сейчас работает: создаю контекст с таймаутом, затем ожидаю srv.Shutdown(ctx) и отменяю контекст в defer cancel() либо подаю по таймауту сигнал <-ctx.Done() для прерывания Shutdown. Правильно? Пока не смог чётко сформулировать, для чего мне nested-контекст. А правильная постановка вопроса - половина решения.
Уже вроде обсуждали в этом канале, стандартный context обеспечивает закрытие по дереву вверх, но это не graceful shutdown (для Graceful Shutdown требуется ожидание обслуживающего детей родителя пока он не обслужит всех своих детей и все его дети не закроются, после чего и сам родитель уже может благополучно закрыться). На деле же при отмене стандартного контекста все горутины отменяющейся ветви получают сигнал закрывающего канала (не важно в каком порядке) после чего все одновременно (и родители и дети) начинают закрываться без ожидания детей, что может привести просто к блочке (когда ребенок отправляет родителю сообщение, а родитель уже завершил свою работу). Я на прошлой неделе уже писал о том что реализовал контекст, который позволяет дожидаться детей путём обертывания горутины ребенка в вызов метода (мой проект: https://github.com/mcfly722/context ) но в процессе разработки данного контекста мной был понят очень важный аспект того, что мы используем вообще не ту структуру данных. Т.е. из контекстов нам нужно вообще НЕ ДЕРЕВО, нам нужен направленный ГРАФ! Это значит что у каждого контекста не должно быть ограничения только в одного родителя (родители являются инфраструктурой для своих детей) поэтому их должно быть множество, а не строго один. И соответственно также должна соблюдаться последовательность закрытия (пока есть контекст который зависит от своих родителей (своей инфраструктуры), его родителей (инфраструктуру) нельзя закрывать). На реализацию я стартанул проект dependency, как будут по нему новости отпишу в чатик.
Go позволяет одинаково именовать пакет в файлах с кодом модуля и с тестами, тогда у нас есть доступ к внутренней реализации модуля (императив), а не только к API модуля (декларатив). В статье нас призывают к TDD, при этом не спускаясь на императивный уровень, а формулируя тесты перед кодингом только на декларативном уровне. Но при рефакторинге я предпочёл бы иметь покрытие на императивном уровне. В наше время этого легко добиться с помощью ChatGPT. Тогда такие императивные модульные тесты не жалко выбрасывать вместе с модифицируемым кодом, если потребуется. Хорошо. А как бы улучшить Developer Experience для декларативных модульных тестов? Сплю и вижу процесс разработки по схеме: Event Modeling > BDD > Integration/Unit Tests (via gherkingen) > code for development via tests for external API of modules - package module_test / whitebox for refactoring > Unit Tests Coverage for internal functions in modules package module / blackbox for modifications (via ChatGPT).
Prompt Engineering - отдельный скилл. Я с ними (ChatGPT / Codeium) постоянно разговариваю, и часто с кривой ухмылкой. Но правильно заданный вопрос - половина решения. Конкретно тут, если вводные строго определены (сигнатура функции и код без сайд-эффектов), то результат вполне годный.
почему "ручка"? потому-что handle
"golang.org/x/exp/slog" можно заменить на "log/slog", т.к. в go.mod заявлено go 1.21
Не нашёл в заметке ссылку на исходники: https://github.com/GolangLessons/sso
Чего ещё не хватает для Graceful Shutdown? Все функции sql-lite имеют двойников с контекстом, например: .Exec вызывает .ExecContext с базовым context.Background(). У меня не хватило ума реализовать nested-контекст для стораджа и для веб-сервера. Как оно сейчас работает: создаю контекст с таймаутом, затем ожидаю srv.Shutdown(ctx) и отменяю контекст в defer cancel() либо подаю по таймауту сигнал <-ctx.Done() для прерывания Shutdown. Правильно? Пока не смог чётко сформулировать, для чего мне nested-контекст. А правильная постановка вопроса - половина решения.
Исходники исправлений: https://github.com/comerc/url-shortener
"в редакцию пришло письмо":
Перевёл!
А почему нет индекса по полю
price
?а где GoLang?
It is based on the following algorithm by Rob Pike
Конфигурация "Две партиции - четыре обработчика"
Не разбирался, что это было. Переставил кафку, теперь не воспроизводится.
Перевёл: Шпаргалка по событийному моделированию
Go позволяет одинаково именовать пакет в файлах с кодом модуля и с тестами, тогда у нас есть доступ к внутренней реализации модуля (императив), а не только к API модуля (декларатив). В статье нас призывают к TDD, при этом не спускаясь на императивный уровень, а формулируя тесты перед кодингом только на декларативном уровне. Но при рефакторинге я предпочёл бы иметь покрытие на императивном уровне. В наше время этого легко добиться с помощью ChatGPT. Тогда такие императивные модульные тесты не жалко выбрасывать вместе с модифицируемым кодом, если потребуется. Хорошо. А как бы улучшить Developer Experience для декларативных модульных тестов? Сплю и вижу процесс разработки по схеме: Event Modeling > BDD > Integration/Unit Tests (via gherkingen) > code for development via tests for external API of modules - package module_test / whitebox for refactoring > Unit Tests Coverage for internal functions in modules package module / blackbox for modifications (via ChatGPT).
Первая звёздочка на GitHub - моя!
Почему?
Буду сам пользоваться этим наглядным примером и всем советовать. Жирный плюс в карму!
Prompt Engineering - отдельный скилл. Я с ними (ChatGPT / Codeium) постоянно разговариваю, и часто с кривой ухмылкой. Но правильно заданный вопрос - половина решения. Конкретно тут, если вводные строго определены (сигнатура функции и код без сайд-эффектов), то результат вполне годный.