Чат на вебсокетах и событийной системе
Перед работой приложения нужно настроить переменные окружения.
- Для локального запуска(приложение локально, rabbit в докере) - нужно:
- Скопировать
local.env
вsciarticle_task/.env
poetry install
- установить проектpoetry shell
- активировать виртуальное окружение
- Скопировать
- Для запуска в докере - скопировать
docker.env
вdocker-compose/.env
- Запустить rabbit через докер.
make storages
- Запустить приложение
- Докер -
make app
- Локально -
make app-local
- Докер -
- Закрыть приложение
make down-all
При выполнении инструкций, следующие утверждения должны быть правдивы:
- Swagger находится на
http://127.0.0.1:8000/api/openapi
. - Подключиться к websocket можно из консоли, используя утилиту
websocat
:websocat ws://127.0.0.1:8000/ws/updates/<Номер комнаты:int>
Приложение построено на событийной системе, использующий паттерн "Посредник"(Mediator)
Ключевые составляющие Mediator:
Command
,CommandHandler
- команды и обработчики для команд. Предполагается, что их активирует пользователь.Event
,EventHandler
- события и обработчики для событий. События могут вызываться из любого места, в том числе при выполнении пользовательской команды.
Используется разделение на слои, похожее на чистую архитектуру.
- Доменная область -
domain
. В ней определены основные сущности, ошибки, события, value-objects. - Инфрастуктура -
infra
. В нем определена логика взаимодействия с внешними системами: websockets, репозитории - Логика -
logic
. В нем содержится вся основная бизнес-логика: mediator, use-cases, interactors, serializers. - Представления -
application
. В нем содержится, соответственно, вся логика работы с IO: FastAPI и FastStream - DI контейнер -
container.py
.
Используется подход для сохранения истории событий - Event sourcing.
Достигается за счет использования прокси-объекта - LoggingEventHandlerProxy
и Event-репозитория.
Плюсы:
- Отдельные компоненты не имеют сильной связи друг с другом.
- Благодаря событийной системе, с одной командой может быть связано несколько событий.
Минусы:
- Сложность в восприятии и понимании.
- Python3
- FastAPI
- FastStream
- RabbitMQ
- DependencyInjector
- Docker, docker-compose
- poetry
- ruff, mypy, pre-commit
- structlog
Ремарка 1: сообщения приходят только в комнату, где может состоять только 2 юзера
Не понял требования, поэтому не стал реализовывать функционал. Необходимы ответы на вопросы:
- Все комнаты должны содержать исключительно два человека?
- Комнаты нужно создавать?
- А нужно ли удалять комнаты?
- Если нужно удалять, то в какой момент? Если из комнаты вышли все люди, либо же вручную?
- Не отправлять в каналы с одним человеком из соображений экономии ресурсов?
В зависимости от ответов будет разная реализация: создание новых endpoint, команд, сценариев для репозиториев, use-cases, проверок.