Я имею дело с приложением python, которое состоит из нескольких распределенных легких компонентов, которые обмениваются данными с помощью RabbitMQ и Kombu.
Компонент прослушивает две очереди и может принимать несколько типов сообщений в каждой очереди. Подклассы могут переопределять способ обработки каждого типа сообщений путем регистрации пользовательских обработчиков. Все это прекрасно работает.
Теперь у меня есть дополнительное требование: каждый компонент должен иметь базовый интерфейс REST/HTML. Идея заключается в том, что вы указываете свой браузер на работающем компоненте и получаете информацию в реальном времени о том, что он сейчас делает (какие сообщения обрабатываются, использование процессора, информация о состоянии, журнал и т.д.).
Он должен быть легким, поэтому после некоторых исследований я остановился на Flask (но я открыт для предложений). В псевдокоде это означает:
class Component:
Queue A
Queue B
...
def setup(..):
# connect to the broker & other initialization
def start(..):
# start the event loop and wait for work
def handle_msg_on_A(self,msg):
# dispatch a msg to a handler depending on the msg type
def handle_msg_on_B(self,msg):
...
...
и добавление нескольких методов просмотра:
@app.route('/')
def web_ui(self):
# render to a template
@app.route('/state')
def get_state(self):
# REST method to return some internal state info as JSON
...
Однако прикрепление веб-интерфейса к классу, как это, нарушает принципы SOLID и создает проблемы с наследованием (подкласс может отображать больше/меньше информации). Декораторы не наследуются, поэтому каждый метод просмотра должен быть явно переопределен и исправлен. Возможно, использование mixin + reflection могло бы как-то работать, но оно кажется хакерским.
Вместо этого можно было бы использовать композицию: поместите веб-материал в отдельный класс, который делегирует URL-маршруты фиксированному предопределенному набору полиморфных методов для вложенного компонента. Таким образом, компоненты не знают о Flask за счет некоторой потери гибкости (набор доступных методов фиксирован).
Теперь я обнаружил Флаги чертежей и Диспетчер приложений и похоже, что они могут принести лучшее, более расширяемое решение. Тем не менее, мне еще предстоит обвести вокруг себя голову.
Я чувствую, что у меня отсутствует шаблон дизайна здесь, и, надеюсь, кто-то с большим количеством флэшек или опыта с этим типом проблем может комментировать.