Skip to content

Repository files navigation

Анализ технического задания

Сразу бросается в глаза, что поле remaining, если оно физически существует в модели слотов — нарушает нормальную форму базы данных. Однако, если мы сделаем сервис, который будет всегда(!) читать только из кеша (и забудем думать про cache stampede), то надо ли на текущем этапе делать эту денормализацию? Возьму на себя смелость и обойдусь без этого поля. Когда весь код будет написан, поле можно будет безболезненного добавить, и это будет незначительный рефакторинг.

Мы будем поддерживать актуальный кеш, в котором поле remaining будет вычисляться: capacity минус сумма холдов со статусом confirmed и сумма холдов со статусом held не старше пяти минут.

Все запросы на изменение данных будут не просто инвалидировать кеш, они будут его перестраивать. Если это окажется неэффективно (много запросов, долгие ответы, нехватка соединений) — мы можем вынести перестройку кеша в асинхронный процесс (очереди).

Примечательно, что запрос на создание брони должен обеспечивать идемпотентность, но при этом в запросе может меняться идентификатор слота. В техническом задании это явно не оговаривается, но кажется очевидным, что идемпотентность должна обеспечиваться не глобально, а в рамках каждого слота по отдельности. Также замечу, что повторный вызов продлевает бронь (это логично).

В техническом задании сказано, что брони живут 5 минут. Это означает, что бронь старше 5 минут не может быть подтверждена. Также сказано, что фоновую очистку можно не реализовывать. Значит у нас в базе будут оставаться устаревшие брони; как с ними поступить?

  1. Сделать дополнительную проверку «не устарела ли бронь» перед её подтверждением?
  2. Или подтверждать даже устаревшую бронь, если есть доступное место?

Предпочту второй вариант: почему бы и нет, это не ломает систему бронирования; а клиенту не нужно лишний раз создавать бронь. А когда (и если) мы внедрим фоновую очистку, то с устаревшими бронями просто перестанем сталкиваться.

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

Запуск

Делаем базу данных

php artisan migrate

Наполняем её тестовыми данными. Тестовые данные подобраны так, чтобы вместимость слота совпадала со значением его первичного ключа. Добавлено три слота.

php artisan db:seed

Запускаем приложение

php artisan serve

Получение списка доступных слотов:

curl -X GET --location "http://127.0.0.1:8000/slots/availability"

Создание брони. Первый вызов — 201. Последующие — 200:

curl -X POST --location "http://127.0.0.1:8000/slots/1/hold" -H "Idempotency-Key: 666bf998-7f27-4285-a966-6f85ed9f31e1"

Подтверждение брони (можно многократно):

curl -X POST --location "http://127.0.0.1:8000/holds/1/confirm"

Отмена брони (можно многократно):

curl -X DELETE --location "http://127.0.0.1:8000/holds/1"

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages