- Created by Unknown User (dv), last modified by Unknown User (gnu-linux) on 29.01.2015
Общие задачи
Описание проблемы
Общие предположения
Требования
# | Требования | User Story | Важность | Примечания |
---|---|---|---|---|
1 | ||||
Общий дизайн
Коллекция Scripts
Таблица sa_maptask заменяется на коллекцию noc.scripts в mongodb. Каждый скрипт, запланированный к выполнению, оформляется как отдельный документ.
Поля документа
Поле | Тип | Описание | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
id | ObjectID | ID задачи | ||||||||||||||||||||||||||||||
group | ObjectID | ID группы задач, если задан | ||||||||||||||||||||||||||||||
timestamp | DateTimeField | Время создания скрипта | ||||||||||||||||||||||||||||||
expires | DateTimeField | Крайний срок выполнения скрипта | ||||||||||||||||||||||||||||||
status | StringField | Статус задачи. Значения:
| ||||||||||||||||||||||||||||||
result_code | IntField | Код завершения скрипта | ||||||||||||||||||||||||||||||
max_retries | IntField | Максимальное количество попыток | ||||||||||||||||||||||||||||||
retries | IntField | Текущее количество попыток | ||||||||||||||||||||||||||||||
object | ForeignKeyField | Ссылка на ManagedObject | ||||||||||||||||||||||||||||||
script | StringField | Название скрипта | ||||||||||||||||||||||||||||||
access_profile | EmbeddedDocumentField | Параметры доступа. Вложенный документ вида
| ||||||||||||||||||||||||||||||
args | DictField | Входные параметры скрипта | ||||||||||||||||||||||||||||||
activator | StringField | Название пула активаторов | ||||||||||||||||||||||||||||||
shard | IntField | ID шарда | ||||||||||||||||||||||||||||||
instance | StringField | Название instance активатора в пуле, который выполняет задачу | ||||||||||||||||||||||||||||||
debug | BooleanField | True, если необходимо создать тушенку | ||||||||||||||||||||||||||||||
caps | DictField | Object capabilities в формате Ключ -> значение |
Результат работы записывается в GridFS в формате JSON (как получено с активатора). В качестве ключа используется id скрипта
Куда записывать тушенку?
API для запуска скрипта
task = managed_object.scripts.get_interfaces(name="Gi 0/1")
Возвращаемая задача имеет тип Future
Использовать ли механизм long running jobs?
API для запуска группы задач
Аналог старых ReduceTask. Используется при необходимости запуска сразу нескольких задач
group = GroupTask() group.add(managed_object.scripts.get_interfaces(name="Gi 0/1", group=group) # Добавить одну задачу group.add(selector, "get_interfaces", name="Gi 0/1") # Добавить несколько задач task = group.run()
Возвращаемая задача имеет тип Future. При запуске задачи создается соответсвующая запись в коллекции Scripts. Зап
Возможно использование нескольких вложенных групп:
group1 = GroupTask() group2 = GroupTask() group1.add(group2) task = group1.run()
Переделка SAE
SAE реализован как HTTP-сервер на базе tornado. В качестве протокола по взаимодействию с активаторами используется JSON-RPC. SAE пассивен, задачи выдаются по запросу активатора. Используется механизм long polling, при котором активаторы, для которых нет задач, зависают на незакрытом коннекте, пока не появятся задачи. Данный механизм позволяет сократить задержку на передачу задания на активатор.
Реализуемые сервисы:
SAService (/SAService/)
Метод | Входные параметры | Выходные параметры | Описание | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
get_tasks |
| Список значений, длиной не более n
| Активатор получает новые задачи, вызывая функцию get_tasks. Для снижения количества HTTP-запросов активатор может запросить несколько задач сразу. Метод подвисает на long polling. Обрыв по таймауту означает, что на данный момент задач нет и необходимо повторить попытку. Для поиска новой задачи используется функция mongodb findAndModify. Запрос для поиска: { status: "W", activator: <activator name>, shard: <shard id> } Для модификации данных используется $set: { status: "R", instance: <activator instance> } | |||||||||||||||||||||||||||
set_result |
| boolean True - результат записан False - ошибка записи | Результат выполнения скрипта. Функция вызывается на каждого скрипта по раздельности | |||||||||||||||||||||||||||
??? throttling
??? Как учитывать object status?
- Сервис /register/ - дергается активатором для мониторинга
- POST /register/
- -> {"expires": seconds}
- Получив ответ активатор должен повторно дернуть /register/ через seconds/2, в случае ошибки - через seconds/8
- POST /register/
- POST /ping/ - дергается NOC-ping с изменениями статуса
- На входе список
- timestamp
- object id
- status
- На входе список
- AutoConf daemon, получает в качестве конфига JSON
- max_sessions
- http client регистрации, крутится в отдельном потоке, реализует сервис /register/
- threadpool - выполняет script runner
- network -- поток с SocketFactory
- dispatcher - отдельный поток, который по запросу script_runner'а запрашивает новые задачи и пересылает на SAE результат (через сервис /task/)
- AutoConf daemon, получает в качестве конфига хосты для пропинговки
- SocketFactory с ping socket'ом, которые занимаются пропинговкой
- sender - отсылает изменения статусов объектов на SAE
- protocol buffers
Открытые вопросы
Отрытые вопросы, не решенные проблемы:
Вопрос | Варианты решения |
---|---|
Related Issues
NOC-291, NOC-1495
Отложенные задачи
Задача | Причина переноса | Примечания |
---|---|---|
Свойства
Epic | |
---|---|
Type | FEATURE |
Status | DRAFT |
Open Date | 2014-01-29 |
Modules | SA |
Language | Russian |
Owner | |
Designer | Unknown User (dv) |
Developers | Unknown User (dv) |
QA | |
Close Date |