【问题标题】:dependency injection, circular dependency in stuartsierra/component for a monitoring component依赖注入,在 stuartsierra/component 中用于监控组件的循环依赖
【发布时间】:2017-04-18 09:12:52
【问题描述】:

我的StuartSierra/component 组件存在循环依赖问题。

我有:

  • webServer 组件
  • 一个Healthcheck 组件,它定期遍历系统以查找实现healthcheck 协议的组件。这是监控的一部分。
  • 实现healthcheck 协议的数据库、作业队列连接等组件。

WebServer 也实现了healthcheck 协议。

我有一个给定系统返回组合路由的函数,允许查询存储在 healthcheck 组件中的最后一个 healthckeck 状态。

所以我现在在这个函数中有这个循环依赖和一个解决方法,即将系统作为var 并在需要时取消引用它,而不是把它作为一个值。

但这很不方便,并且意味着在启动过程中,检查会在一段时间内报告错误的值。

有没有办法在组件中处理这种生命周期?还是这里有设计缺陷?

【问题讨论】:

    标签: dependency-injection clojure health-monitoring


    【解决方案1】:

    与通常的循环依赖一样,您可以通过将一些麻烦的功能提取到一个或多个附加组件中来打破循环来解决此问题。一种方法是将“webserver”组件重命名为“app handler”之类的,并让它包含除基于监控的路由之外的所有路由。它实际上不应该启动网络服务器本身,只是提供一个可用于启动服务器的环处理程序函数。

    此时,添加一个依赖于应用程序处理程序的“监控”组件当然很容易,并且它可以为整个系统生成健康状态(除了网络服务器本身,我们还没有得到) .

    最后一个新的“webserver”组件可以获取应用程序处理程序提供的路由,并启动一个网络服务器,将它们与一个额外的/monitoring 处理程序或其他东西结合起来,它会询问监控组件情况如何。如果您愿意,您可以在此处添加有关网络服务器本身的状态,但实际上如果网络服务器不健康,您将在许多情况下无法通过网络服务器本身说出任何有用的信息。

    组件依赖图总结图:

    http://svgur.com/i/1GY.svg

    显然 Stack Overflow 不支持嵌入 SVG 文件,所以我不得不在外部托管它。


    您可以采取的完全不同的方法是让监控组件完全没有依赖关系,而是基于插件/注册。每个其他系统都将依赖于监控系统,并且作为其启动的一部分,它会通过提供一些回调来回答“我有多健康?”这个问题来注册自己。

    在某些方面我认为这违背了 Component 的精神,因为您正在向依赖图添加隐式向后边缘,但我认为这是一种合理的方法。这更多地证明了“计算机科学中的所有问题都可以通过另一个层次的间接解决”这句古老的格言。在 C 和此类语言中,这通常意味着另一个级别的指针。在函数式语言中,这通常意味着用函数替换值。

    【讨论】:

    • “它实际上不应该启动网络服务器本身,只是提供一个可以用来启动服务器的环处理函数。”。我不确定那会是什么样子? gist.github.com/nha/fa42e22fdad1446d97e96976e382fd0f
    • 我描述的东西更像gist.github.com/amalloy/f281723c6700c1da1cd9905e18e08d83(我不知道组件系统映射的实际语法,所以显然这是一个草图)。
    • 在你的草图中,是monitoring health-check?我尝试了类似的方法,但组件似乎需要映射而不是函数(在它的自述文件中搜索“将像你这样做一样启动”),仅在注入依赖项时。旁注:“在函数式语言中,它通常意味着用函数替换值。”从来没想过这些,有趣!
    猜你喜欢
    • 1970-01-01
    • 2020-03-14
    • 2010-11-29
    • 2018-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-03
    相关资源
    最近更新 更多