Pull to refresh

Comments 44

А что тут комментировать? Комбинируйте машину состояний и REST.
Если точнее, вводите переходные состояния. running -> stopping -> stopped. не забыть indeterminated :)
Как будет выглядеть команда на ребут?
например,

method: PUT
url: /yourmachine/state
body: to-reboot
Нарушение парадигмы REST. put идемпотентный (повторные вызовы не должны ничего менять, если мы сказали один раз a=1, то сколько бы мы это не говорили, a всё время будет равно 1).
Не используйте одну парадигму, комбинируйте, очевидно же! Сделайте один из end-point'ов который отвечает за состояние JSON-RPC.
А вот это уже первый шаг к хаосу. Во-первых, как только у нас появляется хотя бы один не REST URL, то говорить о REST модели не приходится, мы должны начать помнить, что PUT в одном месте идемпотентный, а в другом нет. Или, POST, в одном месте объект создаёт, в другом всего лишь меняет статус.

Смешение RPС и REST'а — это просто ужасно. Единственной разумной областью разграничения может быть GET и POST+PUT. GET — всегда без side effects, с контролируемым кешированием и с красивыми URL'ами, а POST'ы — чистой воды RPC. Так да.

А если 90% PUT'ов будет как REST, а 10% — как RPC, то это прямой путь к бездне сансары и перерождению в программиста на коболе в следующей жизни.
Судя по всему чистый REST к вам не применим. Переходить на RPC только из-за того, что надо иметь 1 точку где REST подход не применим лично я считаю глупой затеей.
У меня такое чувство, что вы не так давно перечитали что-то до забавного теоретическое, или, стало быть, курсы какие прошли…
Как человек два с половиной года использовавший самописный полу-REST полу-хрензнаетчто протокол с обоих сторон могу сказать, что тут нет ничего теоритического. Использование одной штуки для разных вещей верный путь к сотням просранных человекочасов. Просранных глупо и бессмысленно, без отдачи для проекта и с огромным минусом в мораль команды.

Альтернативы конечно есть: писать исчерпывающую документацию, которую потом читают. Вот только не похоже, что тут водятся ребята с фейсбука у которых есть ресурсы для первого и авторитет для второго.
Согласен, но называть сию проблему «онтологической» или ссылаться на проблемы в определенямх — перебор. Просто REST не подходит для одного, и подходит для другого, и достаточно на пальцах объяснить, почему именно.

Вот вы привели адекватный пример. В статье такого не заметил.

В принципе, нарушения парадигмы нет. 1ый клиент (пользователь) записал to-reboot, 2ой клиент (агент виртуальной машины) каким-либо образом (полинг в простейшем случае, но можно и оптимизировать по разному) узнал, что состояние стало to-reboot и изменил его на rebooting. Т.о., при состоянии to-reboot повторные to-reboot ничего не изменят, а при состоянии rebooting повторные вызовы могут что-то поменять, а могут и ничего не поменять (агент восстановит значение ресурса в rebooting на основе своего внутреннего состояния после получения информации о том, что поле изменилось или запустит еще один ребут — в зависимости от того что требуется).

Могут ли идеологически два клиента что-то менять на основе изменений друг друга? Думаю, что могут. Например, легко можно представить двух человек правящих статью в вики подобным образом.

Является ли объединение агента виртуальной машины и обработчика REST-запросов идеологически некорректным действием? Т.к. схема изменения состояний ресурса остается и внешне REST работает так же (по сути для целей оптимизации исключается информирование агента о событии через http и ожидание ответа от него), то с точки зрения REST подобный подход чист.
Дополнительно, уже по статье, подход «vm.send_desired_mem» не отличается от ввода нового параметра desired_mem в REST.

Главное, что нужно понять, это то, что REST — это способ доступа к некоторому пассивному ресурсу (БД по сути), который клиенты (не только люди, но и приложения) могут менять. И он может становится в приложении похожим на активный ресурс в простых случаях, но это не должно смущать при работе с более сложными (то же уменьшение памяти). Какие именно поля должны быть представлены в ресурсе (память или актуальная память с желаемой памятью) зависит от потребностей алгоритмов и данных на вход/выход.
Да, в этой части, согласен, возможно именно так.

Но ребут? Пожалуй, из всего, что я услышал, только создание задачи на ребут (POST /task/reboot) выглядит разумно.
method: PUT
url: /yourmachine/last-reboot-time
body: {{ utcnow + '1 minute' }}
Это уже извращенством попахивает…
планирование евентов в очереди задач противоречит рест-подходу?
Очевидно, что перезагрузка не идемпотентный вызов, то есть мы должны говорить POST. Но 'POST что и куда?'.

Может добавление команды в очередь? Аналогичным образом я бы поступил и с шатдауном. GET power-state — да, PUT power-state — нет, инкапсулируется в команду. POST команды set_desired_mem — да, GET для <утрирую>real_mem_allocated</утрирую>, GET же и для /commands/<set_mem_command_id>, чтобы узнать, что state=warning,mem_requested=32M,mem_allocated=64M.
> Может добавление команды в очередь?
Мне тоже этот вариант кажется вполне логичным и не противоречащим REST-идеологии.
RPC тяжелый? Странно, в питоне его выполнить легче, чем GET-запрос.
Чистый REST вам не подходит, и вы не одиноки в своей проблеме. Для таких ситуаций в прогрессивных странах существует подход REST Web Services, т.е. фактически вы отступаете от идеологии REST (идея рассматривать всё как ресурс), но при этом для вызовов используете не RPC-протокол, а HTTP. Это позволит избежать генерации wsdl, и при этом развяжет вам руки в проектировании API.
UFO just landed and posted this here
Прочитал два раза и честно говоря не понял проблемы использовать POST. Его семантика: доставить сообщение ресурсу. Сообщение может быть «reboot». Как ресурс изменит своё (или не своё) состояние не оговаривается.

Цитируя RFC: «POST is designed to allow a uniform method to cover the following functions:

— Posting a message to a bulletin board, newsgroup, mailing list, or similar group of articles;

The actual function performed by the POST method is determined by the server and is usually dependent on the Request-URI.

The action performed by the POST method might not result in a resource that can be identified by a URI.
»

Таким образом планирование и исполнение задачи перезагрузки VM вполне укладывается в семантику POST. Мало того, если также рассматривать операции вроде создания образа или установки ОС как планирование задач (идентифицируемых и опрашиваемых на предмет состояния выполнения) они тоже прекрасно укладываются в REST.
Так я не понял, в чём проблема у автора? Ну да, одно конкретное решение (REST) не подходит для одной конкретной задачи (управление виртмашинами). А разве кто-то утверждает, что REST — единственный протокол для всего?
UFO just landed and posted this here
Ок, s/протокол/интерфейсный стиль/, это не меняет сути.
Потому что это не REST.
А чем посылка команды на перезагрузку отличается от оформления заказа в интернет магазине? Логика та же, ведь у заказов тоже есть состояния, но это не мешает использовать REST для их работы.
Потому что глагол действия в REST -> PUT и другого быть не может, а в reboot в вашем случае должно находиться состояние.
откройте тайну — в каких случаях в REST использутся POST?
Ошибся глаголом :) я про конкретный вопрос говорил, что неправильно передавать глагол в URL.
Это почему?.. и что изменится если будет

POST /vm333
reboot

?
Очевидно, что перезагрузка не идемпотентный вызов, то есть мы должны говорить POST.

Помоему тут всё правильно.
Я всегда буду обновлять комментарии перед отправкой. Я всегда буду обновлять комментарии перед отправкой.
Потому что глагол действия в REST -> PUT и другого быть не может, а в reboot в вашем случае должно находиться состояние.
UFO just landed and posted this here
> Ведь состояние машины не меняется, как была running, так и остаётся.

У неё есть ещё куча параметров, кроме running. Например uptime. На мой взгляд всё нормально. Конечно REST диктует нам множество правил, но управление довольно детерминированным объектом виртуальной машины обычно укладывается в их рамки. Конечно, в реальном мире иногда приходится эти правила нарушать, но при этом совсем не обязательно скатываться до RPC через HTTP…
В этом случае «начали менять одно, получилось другое» выглядит куда более логично. Особенно, если мы вместо vm.set_memory() будем делать vm.send_desired_mem().
Я не слишком силен в идеологиях, так что не совсем понял, что вам мешает с помощью REST устанавливать desired_mem, а не current_mem, а машина уже будет стремится приблизить свой current_mem к desired_mem?
Т.е. у машины есть ее реальные текущее свойства, которые readonly, и ее текущая конфигурация, с которую мы при необходимости изменяем и на основе которой машина себя подстраивает.
Ага, вот за это уже спасибо. Да, выглядит логично.
У нас есть should_be_state и мы туда делаем PUT.
На самом деле оказалось очень удобно.
UI обновляет should_be_state, а hypervisor — current_state.
Хотя наверное было бы правильнее делать POST to /tasks
с параметрами машины и получать task объект который
затем опрашивать на предмет как идут дела.
Одно другому не мешает, кстати ;)
Sign up to leave a comment.

Articles