Task #80238
openTask #79968: [&] (Tech Story) CourseKey Integration: Requests Based on Queue
[&] CourseKey Integration: Requests Based on Queue: Очередь отправки
Description
coursekey_requests.sql):
- Добавить поле bool для хранения факта отправки. Добавить Индекс.
- Добавить поле для хранения datetime отправки.
- Добавить поля для поддержки цепочек (chain): номер цепочки, порядковый номер запроса в цепочке.
- Поменять типы json полей на json (например RequestParams).
Добавить класс
GEGI\CourseKey\Requests\Request для работы с coursekey_requests.sql.
- Наследовать его от CollectionItem, т.к. коллекция нужна будет нам чтобы массово сохранять ответы в БД.
- Свойства из БД.
Добавить фоновый скрипт
send-coursekey-requests.php:
- Запускается раз в N минут по настройке Period of Synchronization, Minutes.
Работает только если включена Enable CourseKey Synchronization. - Выбирает все не отправленные записи coursekey_requests.sql в коллекцию:
- сортирует их по номеру цепочки и по порядковому номеру запроса в цепочке.
- ограничивает количество не большими порциями (важно выбирать полные цепочки), т.к. отправка частая.
- Отправляет их один за другим и фиксирует ответы в объектах. Затем массово сохраняет их в БД.
- Если запрос в цепочке выполнился с ошибкой:
- Фиксирует ошибку.
- Решает остановить ли цепочку. Нужен гибкий способ настраивать такие решения (будет отдельный класс
ChainSendPolicy). Если остановить, то останавливает и переходит к следующей цепочке. Если можно продолжать, то продолжает.
- Для каждого запроса добавляет фоновую задачу (dispatcher task) пост-обработки. Так делаем, потому что бывают "тяжелые" алгоритмы (например пересчет SAP).
- Фиксирует в отдельном поле Id такой задачи и статус. Таск пост-обработчик после выполнения меняет этот статус.
Добавить класс
GEGI\CourseKey\Requests\Chain для работы с цепочками:
- Содержит массив запросов
GEGI\CourseKey\Requests\Requestс порядковыми номерами (можно использовать индексы массива пронумерованные от 1). - Содержит объект
GEGI\CourseKey\Requests\ChainSendPolicyкоторая объясняет сценарий действий если при отправке в цепочке есть ошибка.
Добавить класс
GEGI\CourseKey\Requests\ChainSendPolicy для описания политик обработки ошибок:
- Содержит имя.
- Содержит метод, который на переданный код ответа ({200, ОК}, {400, User Exists} и др.) возвращает сигнал, что делать: продолжить запросы в цепочке, остановить, повторить, отменить сделанные запросы и др.
Results¶
Разработка ведётся в ветке: feature/79114-coursekey-integration-requests-based-on-queue.- Доработал очередь отправки. Добавлены новые колонки.
- Добавил коллекции для работы с таблицей.
- Добавил фоновый скрипт.
- Добавил класс Chain - который работает с цепочкой.
- Добавил прототип класса ChainSendPolicy.
Files
Related issues
Updated by Mikhail Guschin 11 days ago
- Description updated (diff)
- Assignee deleted (
Mikhail Guschin)
Updated by Maksim Fomin 11 days ago
· Edited
важно выбирать полные цепочки - мы можем использовать метку времени для таких цепочек. Например колонку group: а туда вставлять timestump.
Updated by Mikhail Guschin 11 days ago
- Subject changed from CourseKey Integration: Requests Based on Queue: Очередь отправки to [&] CourseKey Integration: Requests Based on Queue: Очередь отправки
Updated by Maksim Fomin 11 days ago
· Edited
Updated by Mikhail Guschin 5 days ago
- Status changed from New to In Progress
- Assignee set to Maksim Fomin
- Estimated time set to 3.00 h
Updated by Mikhail Guschin 5 days ago
- Assignee changed from Maksim Fomin to Mikhail Guschin
Updated by Maksim Fomin 5 days ago
- Assignee changed from Mikhail Guschin to Maksim Fomin
Updated by Maksim Fomin 4 days ago
· Edited
- В монолите при обновлении сущностей нужно будет вызывать:
// На данный момент собирается массив цепочки. $chainJobs = [ new AddCourse('1','1','1','1','1','1'), new AddUser('1','1','1','1','1','1','1') ]; $chain = new Chain($chainJobs); $chain->Dispatch(); $chain->Dispatch(); // Сохранит цепочку в таблице. - Фоновый скрипт читает очередь, обходит цепочки и устанавливает статусы:
$limit = 10; /** @var SendCourseKeyRequest $command */ $command = SendCourseKeyRequest::Get(); $command->HandleRequests($limit);
В теории ещё можно проходить в цикле и пытаться прочитать 50 строк беря по 5 полных цепочек, т.к. коллекция очищается.
Updated by Maksim Fomin 4 days ago

Updated by Mikhail Guschin about 22 hours ago
Maksim Fomin wrote in #note-5:
Maksim Fomin wrote in #note-3:
важно выбирать полные цепочки - мы можем использовать метку времени для таких цепочек. Например колонку group: а туда вставлять timestump.
Договорились, что можно использовать Uuid для группировки цепочек. Если его нет в проекте, то подключу библиотеку uuid
Ок. Библиотека выглядит живой (крайний стабильный релиз Ноябрь 2023).
Updated by Maksim Fomin about 19 hours ago
- Таблица
IsSent bool SentAt datetime Payload json
- Классы
- Слева классы dto(Job или Command), они совпадают с действием или маршрутом которое нужно совершить в цепочке. Параметры отличаются для каждого маршрута, поэтому и список свойств я решил разделить на разные dto. Далее будет проще понять, что за операция с данными нужна.
- Посредине классы для работы с цепочкой очереди(задачами). Chain - содержит одну Request запись из коллекции с которой производит операции сохранения и обновления статусов. Содержит список массив Jobs, который может передать классу ChainSendPolicy.
- Справа классы коллекции для работы с таблицей. Умеют кодировать payload в json и декодировать обратно в полноценные объекты для дальнейшей работы. В коллекции есть методы для получения списка коллекций с лимитом и offset для пагинации.
