Repository navigation
Conversation
| await self._users.save(user) | ||
|
|
||
| tokens = await self._issue_token_pair(user) | ||
| await self._publish_user_created(user) |
There was a problem hiding this comment.
Оч хочется в подобных местах использовать паттерн Outbox, потому что при краше/эксепшне между L71 и L74 будет несогласованное состояние (не получим уведом о пользаке, хотя инфа записана).
TL;DR Аутбокс состоит из двух этапов: 1) в атомарной транзакции в БД записываются изменения о пользаке и информация о событии в аутбокс-табличку 2) в фоне специальный воркер проверяет аубокс-табличку, отправляет событие в брокер, затем удаляет событие из БД.
Если херанёт в 1), то всё норм, ни записали, ни отправили
Если херанёт в 2), то мы не потеряем инфу о событии, но exactly-once отправку обеспечить уже не можем, нужно будет делать дедупликейт событий на стороне приёмки.
|
|
||
| # App | ||
| APP_NAME: str = "auth-service" | ||
| APP_ENV: str = "development" |
There was a problem hiding this comment.
| APP_ENV: str = "development" | |
| # from typing import Literal | |
| APP_ENV: Literal["development", "staging", "production"] = "development" |
| @field_validator("APP_ENV") | ||
| @classmethod | ||
| def validate_app_env(cls, v: str) -> str: | ||
| allowed = {"development", "staging", "production"} | ||
| if v not in allowed: | ||
| raise ValueError(f"APP_ENV must be one of {allowed}") | ||
| return v |
There was a problem hiding this comment.
| @field_validator("APP_ENV") | |
| @classmethod | |
| def validate_app_env(cls, v: str) -> str: | |
| allowed = {"development", "staging", "production"} | |
| if v not in allowed: | |
| raise ValueError(f"APP_ENV must be one of {allowed}") | |
| return v |
No description provided.