Мне нужно реализовать какой-нибудь скрипт для экспорта данных из одного сервиса в другой. Сервис Origin написан с использованием языка PHP. Служба назначения имеет SOAP API с MQ под капотом, поэтому каждый запрос к этому API преобразуется в сообщение, которое отправляется в очередь и ожидает обработки. Сервер API отвечает на этот запрос только с идентификатором сообщения, поэтому мне нужно выполнить один или несколько дополнительных запросов с этим идентификатором сообщения в качестве параметра, чтобы получить статус и результат обработки моего первоначального запроса.
Основная проблема в том, что у меня много данных для обработки, когда следующий запрос зависит от результата предыдущего запроса. Я собираюсь использовать какую-то службу MQ на стороне клиента, чтобы заставить клиента «ждать» результата успешной обработки предыдущего запроса. На данный момент в стеке нашего проекта есть 2 таких сервиса: Kafka и Gearman. Было бы замечательно решить проблему с использованием этих тем без необходимости установки дополнительных служб.
Экспорт данных в основном будет состоять из иерархических структур с папками и сложными составными элементами. Например, представьте некоторую структуру:
[
'title' => 'Cars',
'folders' => [
[
'title' => 'Chevrolet',
'folders' => [],
'files' => [
['file' => '/path/to/images/dir/camaro.jpg'],
['file' => '/path/to/images/dir/tahoe.jpg']
]
],
]
]
Мне нужно воспроизвести точную структуру в службе назначения через API. Таким образом, в соответствии с функциями API, я должен выполнить несколько запросов:
// Ask API to create folder
>>> ['action' => 'create-folder', 'name' => 'Cars', 'parent' => 'null']
// Get ID of the message in queue
<<< ['status' => 'received', 'message-id' => 123]
// Request message status
>>> ['action' => 'get-message-result', 'message-id' => 123]
// Get ID of the created folder
<<< ['status' => 'created', 'folder-id' => 1]
// Perform next request using ID of created folder as parent ID
>>> ['action' => 'create-folder', 'name' => 'Chevrolet', 'parent' => 1]
<<< ['status' => 'received', 'message-id' => 124]
>>> ['action' => 'get-message-result', 'message-id' => 124]
<<< ['status' => 'pending']
// ... Maybe rerun request multiple times because of server delays
>>> ['action' => 'get-message-result', 'message-id' => 124]
<<< ['status' => 'created', 'folder-id' => 2]
// Upload physical file
>>> ['action' => 'upload-file', 'path' => '/path/to/images/dir/camaro.jpg']
<<< ['status' => 'received', 'message-id' => 125],
>>> ['action' => 'get-message-result', 'message-id' => 125]
// Get path to the uploaded file, generated by server
<<< ['status' => 'created', 'file-name' => '/tmp/_190402934.jpg'],
// Create DB record linked to that physical file
>>> ['action' => 'create-file', 'path' => '/tmp/_190402934.jpg'],
<<< ['status' => 'received', 'message-id' => 126],
>>> ['action' => 'get-message-result', 'message-id' => 126]
<<< ['status' => 'created', 'file-id' => 100],
// ... and so on
Главное, что я хочу показать, это то, что один запрос зависит от другого. Результат запроса не содержит данных об успехе, только идентификатор сообщения в очереди, поэтому для получения данных результата необходимо выполнить неизвестное количество дополнительных запросов после основного. И только после получения необходимых данных (например, идентификатора созданной папки) очередь клиента может перейти к следующему шагу.
Не могли бы вы помочь мне с вашими предложениями по эффективному способу реализации этого? Можно ли это реализовать с помощью Gearman или / и Kafka?
Возможно ли установить какое-либо ограничение на MQ клиента, которое будет ограничивать службу для запуска следующего запроса API только после получения требуемого результата предыдущего запроса (независимо от задержки и количества дополнительных запросов 'get-message-result' между основным запросом) и фактический результат обработки этого запроса)?
Может быть, вы могли бы предложить несколько примеров, статей или книг, где были решены похожие проблемы?