Я имею дело с питоновым приложением, которое состоит из нескольких распределенных легких компонентов, которые обмениваются данными, используя 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 за счет некоторой потери гибкости (набор доступных методов фиксирован).
Я обнаружил Чертежи флэшек и Диспетчеризация приложений , и похоже, что они могут принести лучшее, более расширяемое решение. Тем не менее, мне еще предстоит обернуть вокруг них голову.
Я чувствую, что мне не хватает шаблона дизайна и, надеюсь, кто-нибудь с большим количеством фляжек-фу или опытом работы с подобными проблемами сможет прокомментировать их.