Skip to content

chistyakov/ping_pong

Repository files navigation

Task from job interview

Вам предлагается задача на умение писать и отлаживать цепочные преобразование данных (pipeline вычисления)

Введение

Одну из наших систем можно описать как pipeline, где идет преобразование одного JSON в другой.

От соискателя мы желаем увидеть понимание построение и отладки таких решений - написать такой pipeline в миниатюре, а потом описать способ отладки.

Задание

Написать пример цепочного вычисления (Шаг 1), а затем показать как его можно отлаживать (Шаг 2).

Шаг 1 - написать PING PONG pipeline

Вам необходимо написать 2 примитивных сервиса на Fast API, которые реализуют PING PONG.

  • Сервисы по POST принимают JSON с словарем.
  • Сервис А добавляет в ключ "digits" случайное целое число (с 0 до 100)
  • Сервис B считает на основе массива “digits” среднее, максимум и минимум и кладет в ключи avg, max, min.
  • Сервисы кидают по очереди кидают запросы друг в друга, пока
    Получается PING PONG, где в словарь постепенно добавляются значения.
  • Каждый сервис имеет валидацию данных.
    Для эмуляции валидации, предлагаем при обработке запроса выдавать 400 ошибку, если случайное число от 0 до 10 делится на 3.
  • PING PONG заканчивается, когда один из сервисов отдает 400-ую ошибку

Шаг 2 - описать как отлаживать pipeline

  1. Предложите варианты отладки pipeline, который написали на шаге 1:
  • Когда есть доступ до кода (разработчику)
  • Когда нет доступа до кода (QA)

Примечание: Основная цель отладке, понять в какой момент прервался pipeline и state на этот момент.

  1. Какую дополнительную мета-информацию стоит добавить, чтобы упростить отладку?

Ожидаемый результат

В результате тестового задания ожидается:

  • Ссылка на gitlab/github репозиторий с реализацией pipeline.
    Рекомендуем писать код с расчетом запуска в Docker контейнерах.
  • В репозитории должен лежать README.md файл с описанием подхода к отладке.

Изменения в требованиях

Не получил ответа на уточнения в требованиях. Изменил реализацию, исходя из здравого смысла:

  • Сервис B отправляет в сервис A массив digits.
  • В условии про валидацию данных используется последнее число из массива digits.
  • При ошибке валидации возвращается не 400, а 422 ошибка

Как запускать

make up
curl -i -X POST "http://127.0.0.1:5001/ping" -H  "accept: application/json" -H  "Content-Type: application/json" -d "{\"digits\":[42]}"
make logs

Как отлаживать

Когда есть доступ до кода (разработчику)

Запуск автотестов

make tests

Запуск статического анализа кода

make static_check

Подключение дебаггера

cp docker-compose.override.yml.template docker-compose.override.yml
# insert 'import pdb; pdb.set_trace()' in code
make up
make attach SERVICE=service_a

Настройка хот-релода кода:

cp docker-compose.override.yml.template docker-compose.override.yml
make up
make restart

Перезапуск:

make down
make up

Автоформатирование (black):

make format

Когда нет доступа до кода (QA)

Swagger для сервиса A: http://127.0.0.1:5001/docs

Swagger для сервиса B: http://127.0.0.1:5002/docs

Просмотр логов:

make logs
# одного сервиса
make logs SERVICE=service_a

Настройка логов: файл logging_config.json

X-Correlation-Id

В ответе на HTTP-запросы к сервисам возвращается заголовок X-Correlation-Id.

У цепочки запросов будет один X-Correlation-Id.

Если заголовок не передан, то сервис сгенерирует его.

Желательно настроить в системе аггрегации логов фильтр по X-Correlation-Id.

В Swagger есть возможность передавать заголовок X-Correlation-Id.

Логгируются запросы и ответы, получаемые и отправляемые сервисами.

Вспомогательные ручки:

Получить последние 10 ответов сервиса B по X-Correlation-Id:

curl -X GET "http://127.0.0.1:5001/service_b_responses/{X-Correlation-Id}" -H  "accept: application/json"

Получить последние 10 ответов сервиса A по X-Correlation-Id:

curl -X GET "http://127.0.0.1:5002/service_a_responses/{X-Correlation-Id}" -H  "accept: application/json"

Дальнейшая разработка

  • Если необходимо выполнять более сложные вычисления в сервисе B, то можно переиспользовать предыдущий шаг вычислений.
    Для этого можно считать некриптографический хэш от полученных digits (например, xxhash). Расчитанные значения положить в хэш-мэп. На следущем шаге попробовать получить предыдущие расчитанные значения, применив хэш-функцию к массиву digits без последнего элемента.

  • Объединить Swagger-документации двух сервисов в одну. Улучшить описание.

  • Добавить отправку в Sentry необработанных ошибок.

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

About

Job interview task

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published