Система занимается импортом данных (заказов с интернет магазинов), процесс импорта заказов осуществляется раз в 10 минут по каждому из магазинов. Магазины предоставляют API для получения нужных данных, данные отличаются по типам и структуре. Нужно организовать обработку и сохранение данных.
- Система получает данные по средствам API сторонних сервисов.
- Периодичность получения и обработки происходит раз в 10 минут.
- Данные могут быть разных форматов xml, csv (файлы в пепке web\staticmock)
XML:
<advcampaign_id> - id магазина
<order_id> - id заказа в магазине
<status> - статус заказа
<cart> - сумма заказа
<currency> - валюта
<action_date> - время создания заказа
CSV:
"1" - id магазина
Unique Transaction ID - id заказа в магазине
"approved" - статус заказа
eBay Total Sale Amount - сумма заказа
"USD" - валюта
Click Timestamp - время создания заказа
Импортировать только те у которых Event Type == Winning Bid (Revenue)
Значения id магазина, статус заказа, валюта являются статическими, их значения приведены выше.
- Организовать периодичною обработку, предоставленных файлов.
- Организовать сохранение / обновление данных в БД
Нужно предусмотреть расширение функционала. Возможность добавление новых файлов, других типов и структуры с минимальной затратой времени и ресурсов.
Для реалізації використано фреймворк symfony 3.0.5 Програму реалізовано як консольний додаток. В базі ісінує дві таблиці orders і shop.
- Shop: список магазинів з яких відбувається імпорт.
- Оrders: замовлення які повинні бути збережені.
Таблиці мають звязок один до багатьох. Необхідну періодичність імпорту і захист від повторного запуску забезпечується полем shop.last_import_time воно оновлюється при старті імпорту і під час запису кожної нової позиції в Оrders.
Така реалізація має як плюси так і мінуси
Плюси:
- Убезпечить від зависання імпорту в разі падіння скрипта
- Забезпечить можливість подальшого горизонтального розширення системи
Мінуси:
- Може виникнути ситуація, що імпорт почнеться повторно якщо парсинг одного елемента займе більше часу ніж проміжок між імпортами.
- Додатковий запрос на запис до бази.
На мій погляд при заданій періодичності в 10 хвилин вірогідність повтору імпорту дуже низька тому була обрана саме така реалізація
Щоб забезпечити оновлення відповідного замовлення використовується складений ключ shop_id order_id де shop_id shop.id a order_id ключ з файлу імпортів (повинен бути унфкальним в межах севісу указано в уточненні завдання)
Парсери виділені в окремий бандл ParserBundle. Щоб уникнути виснаження памяті використовуються потокові парсери файлів. Для парсінга XML використано сторонній парсер SimpleXMLReader http://github.com/dkrnl/SimpleXMLReader який довелось трохи форкнути
Установити залежності:
composer update
Провести міграцію бази:
php bin\console doctrine:database:create
php bin\console doctrine:migrations:migrate
Міграція створить базу і заповнить метаданими таблицю shop
Для запуску сервера парсера виконати команду:
php bin\console server:run
Запуск сервера необхідний так як в метаданих забитий шлях до файлів імпорту на цьому ж сервері. Без старту сервера буде помилка читання файлу.
Для старту парсера:
php bin\console parser:start
Команду старту парсера можна забити в якийсь шедулер команд наприклад crontab і запускати хоч кожну хвилину імпорти будуть відбуватись лише раз в 10 хвилин.