我正在处理一个python应用程序,它由多个分布式轻量级组件组成,这些组件使用RabbitMQ&;Kombu进行通信。
一个组件监听两个队列,并且可以在每个队列上接收多个消息类型。子类可以通过注册自定义处理程序重写如何处理每个消息类型。 这一切都很好。
我现在有一个附加的要求,即每个组件必须有一个基本的REST/HTML接口。您可以将浏览器指向正在运行的组件,并获取其当前正在执行的操作的实时信息(正在处理的消息、cpu使用率、状态信息、日志等)
它需要很轻,所以经过一些研究,我决定烧瓶(但我对建议持开放态度)。在伪代码中,这意味着:
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
...
然而,将web UI固定到这样的类上会破坏SOLID原则并带来继承问题(子类可能希望显示更多/更少的信息)。装饰器不是继承的,因此每个视图方法都需要显式重写和重新装饰。也许使用mixin+反射可以起到某种作用,但感觉有点老套。
相反,使用组合可以工作:将web内容放在一个单独的类中,该类将url路由委托给嵌套组件上一组固定的、预定义的多态方法。 这样,组件就不知道烧瓶的存在,代价是灵活性的损失(可用的方法是固定的)。
我现在发现了Flask blueprints和Application Dispatching,看起来它们可以带来更好、更可扩展的解决方案。然而,我还没有把我的头裹在他们身上。
我觉得我错过了一个设计模式,希望有人与更多瓶福或经验与这类问题可以评论。
烧瓶0.7中悄悄地引入了一些您可能感兴趣的内容-Pluggable Views。这些是基于类的端点,而不是基于函数的端点,因此可以使用^{} 方法来管理状态转换(仅在需要时重写它)。
与使用应用程序分派不同,这样做的好处是,您可以在整个应用程序中获得
url_for
支持(而不必在跨应用程序边界的url中硬编码)。您必须确定这是否是应用程序可能遇到的问题。在伪代码中:
如果您有一系列逻辑连接在一起的组件,并且您不想记住将
/prefix
放在每个组件的add_url_rule
调用前面,则可以将蓝图添加到组合中。但是如果你有一系列的组件,它们彼此独立,这就是我要使用的模式。*。另一方面,如果它们需要相互隔离,我将使用文档中推荐的应用程序分派模式。
相关问题 更多 >
编程相关推荐