Обновить
17
-1.6
Andrew Ka@comerc

#кодеротбога

Отправить сообщение

Текущая реализация метода имеет одну критичную дыру в безопасности — он не защищен от брутфорса (перебора паролей).

Это внешняя инфраструктурная задача относительно функциональности. Мы же не пихаем в каждый веб-сервис защиту от DDOS-атак. Например, поможет fail2ban

Как применяется claims - не очень понятно, я бы исправил.

я обычно размещаю их в месте использования, а не рядом с реализацией

Согласен. Можно легко и убедительно обосновать. Но я бы оставлял в комментариях реализуемых методов, что это реализация такого-то интерфейса. Поможет поддерживать код?

Интерфейсы UserSaver и UserProvider реализованы в Storage (как и в предыдущей статье), но тогда контекст можно вынести туда, а не таскать его каждый раз в методах SaveUser() и User(). Или я что-то не учитываю?

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

Нашёл ответ, зачем таскать контексты в каждом методе. Попахивает "предварительной оптимизацией". Даже если предположить, что источники данных для каждого интерфейса могут быть разные, у них вполне себе может быть общий слой Storage (в котором находится базовый контекст).

type My struct{}

func (My) Try() {
	println("My")
}

type My2 struct {
	My
}

func (My2) Try() {
	println("My2")
}

func main() {
	My2{}.Try() // My2
}


Понял, что для структуры serverAPI можно перезаписать методы из встроенной UnimplementedAuthServer. Но зачем прослойка в виде интерфейса Auth, можно же сразу реализовывать интерфейс AuthServer внутри services/auth?

Сервер валидирует и тупо перекладывает данные и ошибки в слой бизнес-логики (services). Но валидация - часть бизнес-логики, а перекладывать данные и ошибки - вообще сомнительное занятие.

/config/config_local.yaml хорошо бы прописать в .gitignore

// TODO: инициализировать объект конфига
// TODO: инициализировать логгер

Лучше бы наоборот. Иначе мы не увидим в логе ошибки инициализации конфига. Но, тут возможна проблема курицы и яйца, т.к. в конфиге определяем, куда складывать логи. Вывод: нужно воспользоваться переменными окружения для конфигурирования логов.

Рекуррентно заходить в поддиректории оно, конечно, в таком виде не будет — это сделать немного сложнее.

Просто добавить две звёздочки для подпапок:

$ protoc -I proto proto/sso/**/*.proto --go_out=./gen/go/ --go_opt=paths=source_relative --go-grpc_out=./gen/go/ --go-grpc_opt=paths=source_relative

На Маке работает, если запускать команду в терминале.

Но если запускать команду внутри go_task, то ругается на "Could not make proto path relative: proto/sso/**/*.proto: No such file or directory"

Возможно, проблема связана с тем, как go_task обрабатывает символы подстановки, такие как **.

Потому для Taskfile.yaml пришлось применить вот такой вариант:

- mkdir -p gen/go & find ./proto/sso -name '*.proto' | xargs protoc -I proto --go_out=./gen/go/ --go_opt=paths=source_relative --go-grpc_out=./gen/go/ --go-grpc_opt=paths=source_relative

почему "ручка"? потому-что 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-контекст. А правильная постановка вопроса - половина решения.

"в редакцию пришло письмо":

Уже вроде обсуждали в этом канале, стандартный context обеспечивает закрытие по дереву вверх, но это не graceful shutdown (для Graceful Shutdown требуется ожидание обслуживающего детей родителя пока он не обслужит всех своих детей и все его дети не закроются, после чего и сам родитель уже может благополучно закрыться). На деле же при отмене стандартного контекста все горутины отменяющейся ветви получают сигнал закрывающего канала (не важно в каком порядке) после чего все одновременно (и родители и дети) начинают закрываться без ожидания детей, что может привести просто к блочке (когда ребенок отправляет родителю сообщение, а родитель уже завершил свою работу). Я на прошлой неделе уже писал о том что реализовал контекст, который позволяет дожидаться детей путём обертывания горутины ребенка в вызов метода (мой проект: https://github.com/mcfly722/context ) но в процессе разработки данного контекста мной был понят очень важный аспект того, что мы используем вообще не ту структуру данных. Т.е. из контекстов нам нужно вообще НЕ ДЕРЕВО, нам нужен направленный ГРАФ! Это значит что у каждого контекста не должно быть ограничения только в одного родителя (родители являются инфраструктурой для своих детей) поэтому их должно быть множество, а не строго один. И соответственно также должна соблюдаться последовательность закрытия (пока есть контекст который зависит от своих родителей (своей инфраструктуры), его родителей (инфраструктуру) нельзя закрывать). На реализацию я стартанул проект dependency, как будут по нему новости отпишу в чатик.

вот этот issue: https://github.com/golang/go/issues/51075



А почему нет индекса по полю price?

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность