|
|
Вопросы
|
|
|
-------
|
|
|
1. >> Что является ресурсом?
|
|
|
* commands -- информация о командах, их список, группы, описания и тд.
|
|
|
* workers(?) -- воркеры, исполняющие команды. Сомнительно.
|
|
|
Возможно есть смысл скрыть реализацию, т.е. воркеров, под некоторыми
|
|
|
другими сущностями. Например, execution и configuration.
|
|
|
workers -- мб оставить как дополнительный низкоуровневый интерфейс.
|
|
|
<< Ресурсы: commands, configuration, execution, workers (low_level)
|
|
|
|
|
|
2. >> Что делать с демонами-воркерами, обнаруженными при инциализации сервера,
|
|
|
но не зарегистрированными в БД?
|
|
|
<< Убиваем их и удаляем PID-файлы.
|
|
|
|
|
|
3. >> Что делать с демонами-воркерами, для которых найдены PID-файлы, по PID
|
|
|
есть информация в БД, но WID из имени PID-файла не совпадает с WID в БД.
|
|
|
<< Убиваем воркера, удаляем PID-файл и запись в БД.
|
|
|
|
|
|
4. >> Стоит ли убрать разделение команд и их id?
|
|
|
<< Не стоит.
|
|
|
|
|
|
5. >> Нужна ли возможность сброса текущих параметров конфигурации?
|
|
|
<< Да.
|
|
|
|
|
|
|
|
|
Взаимодействие с воркером с точки зрения сервера
|
|
|
------------------------------------------------
|
|
|
1. Сервер получает от клиента запрос, POST /configuration/{command_id}. Далее:
|
|
|
|
|
|
* Сервер создает объект воркера команды и запускает с его помощью
|
|
|
демона-рабочего, оставляя его в режиме ожидания конфигурационных данных.
|
|
|
|
|
|
* После создания объекта воркера в БД сохраняется основная информация
|
|
|
необходимая для воссоздания объекта воркера в новом процессе сервера. Такая
|
|
|
ситуация может возникнуть при переходе на новую версию сервера:
|
|
|
|
|
|
- int wid -- идентификатор воркера;
|
|
|
|
|
|
- str socket -- путь к сокету для чтения данных воркера;
|
|
|
|
|
|
- int daemon_pid -- PID демона-воркера для взаимодействия с ним.
|
|
|
|
|
|
* В ответ на запрос сервер получает список доступных ресурсов, включающих
|
|
|
в себя в том числе действия воркера, а также URI этих ресурсов и
|
|
|
доступные для этого URI http-методы. На данном этапе:
|
|
|
|
|
|
- configure (patch) -- изменить некоторые параметры конфигурации;
|
|
|
|
|
|
- cancel (delete) -- закончить конфигурацию без продолжения выполнения.
|
|
|
По сути удаляет данную конфигурацию как ресурс;
|
|
|
|
|
|
- execute (post) -- запустить выполнение команды с дефолтной
|
|
|
конфигурацией. По сути удаляет конфигурацию как ресурс и создает
|
|
|
новый ресурс -- выполнение.
|
|
|
|
|
|
2. Сервер получает от клиента запрос PATCH /configuration/{WID}/parameters,
|
|
|
содержащий в теле конфигурационные данные. Далее:
|
|
|
|
|
|
* Формируется конфигурационное сообщение (1a), содержащее в себе список
|
|
|
объектов, описывающих один или несколько параметров команды, которое
|
|
|
затем отправляется воркеру.
|
|
|
|
|
|
* Oжидается ответ от воркера (1a) с информацией о результатах обработки
|
|
|
параметров, найденных ошибках и т.д, который пересылается клиенту.
|
|
|
|
|
|
* Конфигурационный цикл повторяется.
|
|
|
|
|
|
Возможно стоит добавить на стороне сервера таймаут при получении ответа от
|
|
|
воркера.
|
|
|
|
|
|
3. Сервер получает от клиента запрос POST /executions/{WID}, указывающий
|
|
|
закончить конфигурацию команды и начать выполнение.
|
|
|
Далее:
|
|
|
|
|
|
* Формируется сообщение воркеру (3a), сообщающее уже ему об окончании цикла
|
|
|
конфигурации.
|
|
|
|
|
|
* Если есть неисправленные ошибки, воркер отвечает на него сообщением (4b),
|
|
|
содержащим оповещение о том, что он заканчивает работу;
|
|
|
Если ошибок нет, то сообщением (4a), оповещающим об успешном запуске
|
|
|
скрипта команды.
|
|
|
|
|
|
* В случае, когда обработка параметров прошла с ошибками -- сразу после
|
|
|
выдачи сообщения об ошибках конфигурации, воркер отправляет сообщение
|
|
|
об окончании своей работы, содержащее список ошибок (9b) и (?) ждет
|
|
|
подтверждение от сервера (?).
|
|
|
|
|
|
4. Сервер получает от клиента запрос GET /executions/{WID}/output на
|
|
|
получение имеющихся выходных данных воркера. Далее:
|
|
|
|
|
|
* Cервер читает все, что есть на сокете воркера. Сообщения (5a, 5b или 6a)
|
|
|
на сокете разделены нулевым символом '\0'. Собирается список полных
|
|
|
сообщений на сокете, формируется сообщение, содержащее этот список,
|
|
|
которое отправляется клиенту.
|
|
|
|
|
|
5. Сервер получает от клиента запрос PATCH /executions/{WID}/input на передачу
|
|
|
воркеру ввода, который был запрошен последним в одном из сообщений ранее
|
|
|
переданных клиенту через сервер. Далее:
|
|
|
|
|
|
* Сервер формирует сообщение (7a) воркеру с данными ввода и отправляет его
|
|
|
воркеру. Если данных нет, что означает, что ввод был сброшен
|
|
|
пользователем, воркер отправляет серверу сообщение (7b) об некорректном
|
|
|
вводе, а метод input объекта ввода/вывода кидает в скрипте специальное
|
|
|
исключение.
|
|
|
|
|
|
Возможно, необходимо убеждаться в том, что данные успешно получены воркером.
|
|
|
Воркер должен ответить сообщением (8a) об успешном получении данных.
|
|
|
|
|
|
- Если данное сообщение не получено в течение некоторого времени
|
|
|
(таймаута) -- выполняем некоторые действия по диагностике и устранению
|
|
|
последствий ошибки, затем отправляем клиенту сообщение, сообщающее о том,
|
|
|
что воркер закончил работу, и содержащее последние сообщения, полученные
|
|
|
от воркера, если таковые имеются.
|
|
|
|
|
|
- Если сообщение об успешном вводе в воркер получено -- отправляем
|
|
|
соответствующее сообщение клиенту.
|
|
|
|
|
|
6. Работа воркера закончилась в результате успешного выполнения команды,
|
|
|
или было прервано клиентом командой stop, или по причине ошибок, возникших
|
|
|
при выполнении скриптов команды. Далее:
|
|
|
|
|
|
* Воркер отправляет на сервер одно из двух специальных сообщений,
|
|
|
оповещающих об окончании работы:
|
|
|
|
|
|
- Содержащее также информацию об ошибках (9b), если таковые
|
|
|
были, неотправленных по каким-то причинам сообщениях (?) или о факте
|
|
|
выполнения команды stop.
|
|
|
|
|
|
- Содержащие только объявление об окончании выполнения команды, то есть
|
|
|
состояния run.
|
|
|
|
|
|
В зависимости от того, возможно ли чтение из сокета, когда процесс воркера
|
|
|
уже закрыт сервер будет или не будет отправлять сообщение разрешающее
|
|
|
воркеру прекратить работу, но клиент его видеть не должен. По факту
|
|
|
получения конечного сообщения и, возможно, данных вместе с ним, клиенту
|
|
|
будет присылаться специальное сообщение.
|
|
|
|
|
|
|
|
|
Контекст воркера
|
|
|
----------------
|
|
|
worker_state -- состояние воркера;
|
|
|
socket_context -- контекст чтения сокета воркера;
|
|
|
worker_output -- вывод воркера перед его выключением сервера.
|
|
|
|
|
|
|
|
|
Что делать
|
|
|
----------
|
|
|
[*] Проверить возможность чтения сервером данных из сокета уже закрытого
|
|
|
воркера. Если такой возможности нет, предусмотреть обработку завершения и
|
|
|
успешной, и некорректной работы воркера с передачей всех необходимых
|
|
|
сообщений. Сделать это внутри воркера.
|
|
|
Итог: чтение из сокета убитого демона возможно.
|
|
|
|
|
|
[ ] Добавить в воркер цикл конфигурации или его тестовый вариант;
|
|
|
|
|
|
[*] Убрать на стороне интерфейса клиента лишний шаг создания объекта воркера;
|
|
|
|
|
|
[*] Убрать self._runner_process и self._pid_file, они в таком случае не нужны;
|
|
|
|
|
|
[*] PID-файл демона удаляем сразу после чтения;
|
|
|
|
|
|
[ ] Реализовать описанный ниже протокол взаимодействия сервера с воркером;
|
|
|
|
|
|
[ ] Добавить в метод kill воркера чтение всего содержимого сокета перед его
|
|
|
удалением.
|
|
|
|
|
|
[ ] Разработать HAL-формат сообщений об ошибках вместо HTTPException.
|
|
|
|
|
|
[*] Сделать метод read воркера асинхронным.
|
|
|
|
|
|
[ ] На случай если воркер убит через SIGKILL -- поскольку обработку
|
|
|
такого завершения работы воркера в самом воркере организовать невозможно,
|
|
|
добавить дополнительную проверку is_alive воркера и предусмотреть обработку
|
|
|
этой ситуации.
|
|
|
|
|
|
[ ] Добавить главный блок try-catch-finally в воркер. В раздел finally добавить
|
|
|
отправку сообщения об окончании работы воркера. В зависимости от
|
|
|
возможности читать данный из сокета законченного процесса воркера, ждать
|
|
|
или не ждать ответ сервера по поводу окончания работы воркера;
|
|
|
|
|
|
[ ] Добавить предварительно деление воркеров по состояниям, вероятно добавить
|
|
|
WorkersPool;
|
|
|
|
|
|
[ ] Добавить состояния воркера:
|
|
|
- config -- воркер в состоянии конфигурации, Т.е. ждёт значения
|
|
|
параметров или собщение об окончании конфигурации;
|
|
|
- exec -- воркер в процессе выполнения команды;
|
|
|
- input -- воркер в процессе ожидания ввода пользователя;
|
|
|
- finish -- воркер в состоянии завершения некоторого состояния.
|
|
|
|
|
|
[ ] Реализовать предварительно REST API в соответствии с наработками;
|
|
|
|
|
|
[ ] Решить, какое значение должны иметь заголовки Content-Type и Accept:
|
|
|
- application/json;
|
|
|
- application/hal+json;
|
|
|
- application/vnd.cphl+json;
|
|
|
- application/vnd.api+json.
|
|
|
Подумать над версионированием API;
|
|
|
|
|
|
[ ] Добавить в ответы сервера обозначения о кэшируемости и некэшируемости,
|
|
|
проработать кэширование в целом, определить, что должно кэшироваться, а что
|
|
|
нет;
|
|
|
|
|
|
[ ] Проработать механизм остановки взаимодействия сервера с клиентом и
|
|
|
возвращения к нему после переподключения клиента, перезагрузки сервера, а
|
|
|
также при этих обоих событиях;
|
|
|
|
|
|
[ ] Добавить проверку во время инициализации сервера наличия PID-файлов
|
|
|
демонов-воркеров:
|
|
|
- Если такие есть -- проверить, что это за процессы;
|
|
|
- Если такие процессы не существуют или не являются воркерами -- удалить
|
|
|
эти PID-файлы;
|
|
|
- Если процессы существуют, являются воркерами и есть информация о них
|
|
|
в БД -- проверяем соответствие PID и WID.
|
|
|
-- Если все совпадает -- удаляем PID-файлы и далее создаем объекты
|
|
|
воркеров по информации в БД;
|
|
|
-- [Q#3] Если есть несовпадения -- убиваем воркер, PID-файл и
|
|
|
записи в БД;
|
|
|
- [Q#2] Если процессы существуют, являются воркерами, но в БД о них нет
|
|
|
информации -- наверное, удаляем PID-файлы и пытаемся убить этих
|
|
|
воркеров с помощью их PID.
|
|
|
|
|
|
|
|
|
Интерфейс сервера
|
|
|
-----------------
|
|
|
REST-интерфейс (вроде). Представляем состояния воркеров в виде ресурсов или
|
|
|
объектов. В соответствии с HATEAOS присылаем URI на ресурсы и действия воркера,
|
|
|
которые доступны в тот или иной момент. Для этого применяем формат
|
|
|
json-сообщений напоминающий HAL или CPHL (не очень распространенный формат).
|
|
|
Различие от HAL в наличии атрибута "methods" в "_links".
|
|
|
|
|
|
* root -- корневой ресурс, являющийся точкой входа для всего API. Возможно,
|
|
|
стоит создать алиас /index или заменить на него.
|
|
|
|
|
|
- GET / -- получить доступные корневые ресурсы;
|
|
|
* request:
|
|
|
|
|
|
null
|
|
|
|
|
|
* response:
|
|
|
Media-Type: application/hal+json
|
|
|
Cache-Control: public
|
|
|
|
|
|
{
|
|
|
"data": {
|
|
|
// Some information about server.
|
|
|
},
|
|
|
"_links": {
|
|
|
"commands": {
|
|
|
"href": "/commands/"
|
|
|
},
|
|
|
"workers": {
|
|
|
"href": "/workers/"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
{
|
|
|
"meta": {
|
|
|
// Server info
|
|
|
},
|
|
|
"links": {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
* сommands -- совокупность данных о командах, доступных для запуска на
|
|
|
сервере.
|
|
|
|
|
|
- GET /commands/ -- получить список команд;
|
|
|
* request:
|
|
|
Media-Type: application/json
|
|
|
|
|
|
{
|
|
|
"gui": {true/false}
|
|
|
}
|
|
|
|
|
|
* response:
|
|
|
Media-Type: application/hal+json
|
|
|
Cache-Control: private
|
|
|
|
|
|
{
|
|
|
"{command_id}": {
|
|
|
"data": {
|
|
|
// Some command info.
|
|
|
},
|
|
|
"_links": {
|
|
|
"self": {
|
|
|
"href": "/commands/{CID}"
|
|
|
},
|
|
|
"parameters": {
|
|
|
"href": "/commands/{CID}/parameters"
|
|
|
},
|
|
|
"cofigure": {
|
|
|
"href": "/configs/{CID}"
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
...
|
|
|
}
|
|
|
|
|
|
- GET /commands/{command}/ -- получить информацию об указанной команде, a
|
|
|
также ее параметры. Запрос используемый
|
|
|
консольным клиентом;
|
|
|
* request:
|
|
|
|
|
|
null
|
|
|
|
|
|
* response:
|
|
|
Media-Type: application/hal+json
|
|
|
Cache-Control: private
|
|
|
|
|
|
{
|
|
|
"data": {
|
|
|
// Some command info.
|
|
|
},
|
|
|
"_links": {
|
|
|
"self": {
|
|
|
"href": "/commands/{CID}"
|
|
|
},
|
|
|
"parameters": {
|
|
|
"href": "/commands/{CID}/parameters"
|
|
|
}
|
|
|
"cofigure": {
|
|
|
"href": "/configuration/{CID}"
|
|
|
}
|
|
|
},
|
|
|
"_embedded": {
|
|
|
"parameters": {
|
|
|
"data": [
|
|
|
{
|
|
|
"group_id": "{group_id}",
|
|
|
"parameters": [...]
|
|
|
},
|
|
|
...
|
|
|
],
|
|
|
"_links":
|
|
|
"self": {
|
|
|
"href": "/commands/{CID}/parameters"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- GET /commands/{CID}/parameters -- получить параметры указанной команды;
|
|
|
* request:
|
|
|
|
|
|
null
|
|
|
|
|
|
* response:
|
|
|
|
|
|
{
|
|
|
"data": [
|
|
|
{
|
|
|
"group_id": "{group_id}",
|
|
|
"parameters": [...]
|
|
|
},
|
|
|
...
|
|
|
],
|
|
|
"_links": {
|
|
|
"self": {
|
|
|
"href": "/commands/{CID}/parameters"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
* configs -- совокупность объектов воркеров, находящихся в состоянии
|
|
|
конфигурации.
|
|
|
|
|
|
- POST /configs/{command} -- создать конфигурацию;
|
|
|
201 -- конфигурация уже создана;
|
|
|
404 -- команды с указанным id нет;
|
|
|
400 -- неправильный формат запроса.
|
|
|
* request:
|
|
|
|
|
|
null
|
|
|
|
|
|
* response:
|
|
|
|
|
|
{
|
|
|
"_links": {
|
|
|
"configure": {
|
|
|
"href": "/configs/{WID}/parameters"
|
|
|
},
|
|
|
"execute": {
|
|
|
"href": "/executions/{WID}"
|
|
|
},
|
|
|
"cancel": {
|
|
|
"href": "/configs/{WID}"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- PATCH /configs/{WID}/parameters -- изменить конфигурацию
|
|
|
указанными в теле значениями;
|
|
|
404 -- конфигурации с указанным
|
|
|
WID нет;
|
|
|
400 -- неправильный формат
|
|
|
запроса.
|
|
|
* request:
|
|
|
|
|
|
[
|
|
|
{"id": "{param_id}", "value": "{param_value}"},
|
|
|
...
|
|
|
]
|
|
|
|
|
|
* response:
|
|
|
|
|
|
{
|
|
|
"data": {
|
|
|
"{param_id}": "{error_message}",
|
|
|
...
|
|
|
},
|
|
|
"_links": {
|
|
|
"configure": {
|
|
|
"href": "/configs/{WID}/parameters"
|
|
|
},
|
|
|
"cancel": {
|
|
|
"href": "/configs/{WID}"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
OR
|
|
|
|
|
|
{
|
|
|
"_links": {
|
|
|
"configure": {
|
|
|
"href": "/configs/{WID}/parameters"
|
|
|
},
|
|
|
"execute": {
|
|
|
"href": "/executions/{WID}"
|
|
|
},
|
|
|
"cancel": {
|
|
|
"href": "/configs/{WID}"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- PUT /configs/{WID}/parameters -- заменить конфигурацию с
|
|
|
использованием указанных в теле
|
|
|
запроса значений. Пустой набор
|
|
|
значений позволяет сбросить
|
|
|
конфигурацию;
|
|
|
* request:
|
|
|
|
|
|
[
|
|
|
{"id": "{param_id}", "value": "{param_value}"},
|
|
|
...
|
|
|
]
|
|
|
|
|
|
* response:
|
|
|
|
|
|
{
|
|
|
"data": {
|
|
|
"{param_id}": "{error_message}",
|
|
|
...
|
|
|
},
|
|
|
"_links": {
|
|
|
"configure": {
|
|
|
"href": "/configs/{WID}/parameters"
|
|
|
},
|
|
|
"cancel": {
|
|
|
"href": "/configs/{WID}"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
OR
|
|
|
|
|
|
{
|
|
|
"_links": {
|
|
|
"configure": {
|
|
|
"href": "/configs/{WID}/parameters"
|
|
|
},
|
|
|
"execute": {
|
|
|
"href": "/executions/{WID}"
|
|
|
},
|
|
|
"cancel": {
|
|
|
"href": "/configs/{WID}"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- DELETE /configs/{WID} -- закончить конфигурации без выполнения
|
|
|
команды.
|
|
|
* request:
|
|
|
|
|
|
null
|
|
|
|
|
|
* response:
|
|
|
|
|
|
[
|
|
|
{
|
|
|
"data": {
|
|
|
"type": "output",
|
|
|
"logging": {logging_level/null},
|
|
|
"text": "{message_text}",
|
|
|
"source": "{source_script}",
|
|
|
}
|
|
|
},
|
|
|
...
|
|
|
]
|
|
|
|
|
|
* executions -- совокупность объектов воркеров, находящихся в состоянии
|
|
|
исполнения.
|
|
|
|
|
|
- POST /executions/{WID} -- создать новое исполнение из конфигурации;
|
|
|
201 -- исполнение создано;
|
|
|
409 -- исполнение с этим WID уже есть;
|
|
|
400 -- неправильный формат запроса.
|
|
|
404 -- конфигурация не найдена.
|
|
|
* request:
|
|
|
|
|
|
null
|
|
|
|
|
|
* response:
|
|
|
|
|
|
- Response Code: 201
|
|
|
|
|
|
{
|
|
|
"_links": {
|
|
|
"output": {
|
|
|
"href": "/executions/{WID}/output"
|
|
|
},
|
|
|
"stop": {
|
|
|
"href": "/executions/{WID}"
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- DELETE /executions/{WID} -- удалить исполнение, происходит путем
|
|
|
отправки в скрипт SIGINT;
|
|
|
* request:
|
|
|
|
|
|
null
|
|
|
|
|
|
* response (возвращает список непереданных сообщений, если они есть):
|
|
|
|
|
|
[
|
|
|
{
|
|
|
"data": {
|
|
|
"type": "output",
|
|
|
"logging": {logging_level/null},
|
|
|
"text": "{message_text}",
|
|
|
"source": "{source_script}",
|
|
|
}
|
|
|
},
|
|
|
...
|
|
|
]
|
|
|
|
|
|
- GET /executions/{WID}/output -- получить список имеющихся сообщений от
|
|
|
команды;
|
|
|
* request:
|
|
|
|
|
|
null
|
|
|
|
|
|
* response (необходимость остановить выполнение определяется по
|
|
|
Response Code):
|
|
|
|
|
|
[
|
|
|
{
|
|
|
"data": {
|
|
|
"type": "output",
|
|
|
"logging": {logging_level/null},
|
|
|
"text": "{message_text}",
|
|
|
"source": "{source_script}",
|
|
|
}
|
|
|
},
|
|
|
{
|
|
|
"data": {
|
|
|
"type": "input",
|
|
|
"text": "{input_message}"
|
|
|
"source": "{source_script}"
|
|
|
},
|
|
|
"_links": {
|
|
|
"input": {
|
|
|
"href": "/executions/{WID}/input",
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
]
|
|
|
|
|
|
- PATCH /executions/{WID}/input -- отправить в воркер некоторый ввод;
|
|
|
* request (если null, значит ввод прерывается):
|
|
|
|
|
|
{
|
|
|
"data": {input_data/null}
|
|
|
}
|
|
|
|
|
|
* response:
|
|
|
- Response Code: 200
|
|
|
|
|
|
null
|
|
|
|
|
|
- Response Code: 404
|
|
|
|
|
|
{
|
|
|
"error": "Execution {WID} is not found"
|
|
|
}
|
|
|
|
|
|
- Response Code: 400
|
|
|
|
|
|
{
|
|
|
"error": "Input message is not correct"
|
|
|
}
|
|
|
|
|
|
* workers -- вся совокупность воркеров.
|
|
|
|
|
|
- GET /workers/ -- получить список демонов-воркеров и информацию о них;
|
|
|
* request:
|
|
|
|
|
|
null
|
|
|
|
|
|
* response:
|
|
|
|
|
|
{
|
|
|
"{WID}": {
|
|
|
"data": {
|
|
|
"socket": "{socket_path}",
|
|
|
"command": "{worker_command}",
|
|
|
"pid": "{daemon_pid}",
|
|
|
}
|
|
|
"_links": {
|
|
|
"kill": {
|
|
|
"href": "/workers/{WID}",
|
|
|
"methods": ["delete"]
|
|
|
}
|
|
|
}
|
|
|
},
|
|
|
...
|
|
|
}
|
|
|
|
|
|
- DELETE /workers/{WID} -- отправить сигнал SIGKILL демону-воркеру;
|
|
|
* request:
|
|
|
|
|
|
null
|
|
|
|
|
|
* response (сообщения полученные от убитого воркера):
|
|
|
|
|
|
[
|
|
|
{
|
|
|
"data": {
|
|
|
"type": "output",
|
|
|
"logging": {logging_level/null},
|
|
|
"text": "{message_text}",
|
|
|
"source": "{source_script}",
|
|
|
}
|
|
|
},
|
|
|
...
|
|
|
]
|
|
|
|
|
|
|
|
|
Протокол взаимодействия воркера и сервера
|
|
|
-----------------------------------------
|
|
|
Все сообщения представляют собой json-структуры, включающие в себя 3 поля:
|
|
|
- state -- состояние воркера:
|
|
|
* Если сообщение пришло воркеру от сервера, тогда это поле указывает
|
|
|
воркеру, какое состояние он должен принять;
|
|
|
* Если сообщение пришло серверу от воркера, тогда это поле указывает на
|
|
|
текущее состояние воркера.
|
|
|
|
|
|
- status -- статус текущего состояния:
|
|
|
0 -- состояние корректно;
|
|
|
1 -- состояние некорректно.
|
|
|
|
|
|
- data -- некоторые данные, структура которых может быть любой.
|
|
|
|
|
|
1. Данные конфигурации от клиента.
|
|
|
a. Продолжить конфигурацию указанными значениями:
|
|
|
|
|
|
{
|
|
|
"state": "config",
|
|
|
"status": 0,
|
|
|
"data": [
|
|
|
{"id": "{param_id}", "value": "{parameter_value}"},
|
|
|
...
|
|
|
]
|
|
|
}
|
|
|
|
|
|
b. Сбросить конфигурацию и продолжить указанными значениями:
|
|
|
|
|
|
{
|
|
|
"state": "config",
|
|
|
"status": 1,
|
|
|
"data": [
|
|
|
{"id": "{param_id}", "value": "{parameter_value}"},
|
|
|
...
|
|
|
]
|
|
|
}
|
|
|
|
|
|
2. Ответ воркера по данным конфигурации.
|
|
|
a. Все параметры конфигурации корректны:
|
|
|
|
|
|
{
|
|
|
"state": "config",
|
|
|
"status": 0,
|
|
|
"data": null
|
|
|
}
|
|
|
|
|
|
b. Некоторые параметры конфигурации некорректны:
|
|
|
|
|
|
{
|
|
|
"state": "config",
|
|
|
"status": 1,
|
|
|
"data": {
|
|
|
"{param_id}": "{error_message}",
|
|
|
...
|
|
|
}
|
|
|
}
|
|
|
|
|
|
3. Запрос на окончание конфигурации от клиента.
|
|
|
a. Закончить конфигурацию, начать выполнение команды:
|
|
|
|
|
|
{
|
|
|
"state": "finish",
|
|
|
"status": 0,
|
|
|
"data": null
|
|
|
}
|
|
|
|
|
|
b. Закончить конфигурацию и работу воркера:
|
|
|
|
|
|
{
|
|
|
"state": "finish",
|
|
|
"status": 1,
|
|
|
"data": null
|
|
|
}
|
|
|
|
|
|
4. Ответ воркера на запрос об окончании конфигурации:
|
|
|
a. Закончить конфигурацию, начать выполнение команды:
|
|
|
|
|
|
{
|
|
|
"state": "finish",
|
|
|
"status": 0,
|
|
|
"data": null
|
|
|
}
|
|
|
|
|
|
b. Закончить конфигурацию и работу воркера:
|
|
|
|
|
|
{
|
|
|
"state": "finish",
|
|
|
"status": 1,
|
|
|
"data": {
|
|
|
"{param_id}": "{error_message}",
|
|
|
...
|
|
|
}
|
|
|
}
|
|
|
|
|
|
5. Сообщение с выводом воркера.
|
|
|
a. Сообщение из скрипта при его "штатной" работe:
|
|
|
|
|
|
{
|
|
|
"state": "exec",
|
|
|
"status": 0,
|
|
|
"data": {
|
|
|
"type": "message",
|
|
|
"logging": {logging_level/null},
|
|
|
"text": "{message_text}",
|
|
|
"source": "{source_script}"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
b. Сообщение об ошибке приводящей к завершению выполнения скрипта и
|
|
|
команды:
|
|
|
|
|
|
{
|
|
|
"state": "exec",
|
|
|
"status": 1,
|
|
|
"data": {
|
|
|
"error": "{error_message}",
|
|
|
"source": "{source_script}"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
6. Сообщение с запросом на ввод.
|
|
|
a. Состояние "input" -- воркер в состоянии ожидания ввода:
|
|
|
{
|
|
|
"state": "input",
|
|
|
"status": 0,
|
|
|
"data": {
|
|
|
"text": "{message_text}",
|
|
|
"source": "{source_script}"
|
|
|
}
|
|
|
}
|
|
|
|
|
|
7. Сообщение от клиента с данными.
|
|
|
a. Ввод успешно выполнен и передается:
|
|
|
|
|
|
{
|
|
|
"state": "input",
|
|
|
"status": 0,
|
|
|
"data": "{client_data}"
|
|
|
}
|
|
|
|
|
|
b. Ввод данных прерван, данных не будет:
|
|
|
|
|
|
{
|
|
|
"state": "input",
|
|
|
"status": 1,
|
|
|
"data": null
|
|
|
}
|
|
|
|
|
|
8. Сообщение от воркера о получении ввода.
|
|
|
a. Ввод успешно получен, о чем говорит переход в состояние выполнения со
|
|
|
статусом 0, т.е. без ошибок:
|
|
|
|
|
|
{
|
|
|
"state": "exec",
|
|
|
"status": 0,
|
|
|
"data": null
|
|
|
}
|
|
|
|
|
|
9. Сообщение воркера об окончании работы:
|
|
|
a. Успешное окончание работы:
|
|
|
|
|
|
{
|
|
|
"state": "finish",
|
|
|
"status": 0,
|
|
|
"data": null
|
|
|
}
|
|
|
|
|
|
b. Работа воркера была прервана или закончилась с ошибками:
|
|
|
|
|
|
{
|
|
|
"state": "finish",
|
|
|
"status": 1,
|
|
|
"data": [
|
|
|
"{error_message}",
|
|
|
...
|
|
|
]
|
|
|
}
|